<?php

namespace App\V3\V3_2_7\Services;

use App\V3\V3_2_7\Models\OperMainAccountModel;
use App\V3\V3_2_7\Models\SupplierCustomerModel;
use App\V3\V3_2_7\Services\StorageManageService;
use App\V3\V3_2_7\Models\LogOutPackageModel;
use App\V3\V3_2_7\Models\LogOutStorageModel;
use App\V3\V3_2_7\Models\MaterielProductContentModel;
use App\V3\V3_2_7\Models\MaterielsTypeModel;
use App\V3\V3_2_7\Models\MaterielTypeModel;
use App\Helper\Utils\TimeUtil;
use App\Services\MessageService;
use App\V3\V3_2_7\Models\StorageBatchModel;
use App\V3\V3_2_7\Models\StorageModel;
use Exception;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use App\V3\V3_2_7\Models\SerialNumberModel;
use App\V3\V3_2_7\Models\AdminModel;
use App\V3\V3_2_7\Models\AdminAddendumModel;
use App\V3\V3_2_7\Models\SalesReturnModel;
use App\Services\CommonService;
use Illuminate\Support\Carbon;
use App\V3\V3_2_7\Models\BarterModel;
use App\V3\V3_2_7\Models\BarterLogisticsInfoModel;
use App\V3\V3_2_7\Models\BarterOutSerialNumberModel;
use App\V3\V3_2_7\Models\BarterGoodsDetailModel;
use App\V3\V3_2_7\Models\SalesOutSerialNumberModel;
use App\V3\V3_2_7\Models\SalesReturnGoodsBatchModel;
use App\V3\V3_2_7\Models\SalesReturnGoodsDetailModel;
use App\V3\V3_2_7\Models\SalesReturnLogisticsInfoModel;
use App\V3\V3_2_7\Models\CheckModel;
use App\V3\V3_2_7\Models\SellModel;
use App\V3\V3_2_7\Models\BarterDriverModel;
use App\V3\V3_2_7\Models\ProductOrderModel;
use App\V3\V3_2_7\Models\StorageManageModel;
use App\V3\V3_2_7\Models\BarterOtherChargesModel;
use App\V3\V3_2_7\Models\TallyModel;
use App\V3\V3_2_7\Models\BarterOutStorageModel;
use App\V3\V3_2_7\Models\SalesReturnInStorageModel;
use App\V3\V3_2_7\Models\LogInStorageModel;
use App\V3\V3_2_7\Models\BarterPayRecordModel;

class BarterService
{
    /**
     * 新建换货
     * @param unknown $data
     * @param number $isUseShelf
     * @param number $isUsePackagesComponents
     * @return number
     * @throws Exception
     */
    static public function addBarter($data, $isUseShelf = 0, $isShareShelfLocation, $isUsePackagesComponents = 0)
    {
        //开启事务
        DB::beginTransaction();
        try {
            $money = 0;//总金额
            $serialData = [];
            $materielInfo = [];
            $productMaterielId = [];
            $sellGoodsList = [];
            $barterData = $data;
            unset($data['logTime']);
            unset($data['barter_info']);
            unset($data['create_time']);
            unset($data['barter_goods_info']);
            unset($data['barter_logistics_info']);

            //创建换货单信息
            $barterId = BarterModel::insertGetId($data);
            if (!empty($barterData['barter_goods_info'])) {
                //商品详细添加
                $goodsInfo = json_decode($barterData['barter_goods_info'], true);
                foreach ($goodsInfo as $key => $value) {
                    //仓库信息
                    $storageInfo = StorageModel::where([
                        'id' => $value['storage_id'],
                        'main_id' => $barterData['main_id'],
                        'delete_flag' => 0,
                    ])->first();
                    if (empty($storageInfo)) {
                        throw new Exception('换货仓库`' . $value['storage_name'] . '`不存在');
                    }
                    if (empty($value['shelf_id']) || empty($value['location_id'])) {
                        if (!empty($isShareShelfLocation)) {
                            throw new Exception('您开启强制选择货架及库位，请选择！');
                        }
                        $shelfId = 0;
                        $locationId = 0;
                        $sfData = ShelfService::get_default($value['storage_id']);
                        if (!empty($sfData)) {
                            $shelfId = $sfData['id'];
                            $lData = ShelfService::get_default($sfData['id'], 2);
                            $locationId = $lData['id'];
                        }
                        $value['shelf_id'] = $shelfId;
                        $value['location_id'] = $locationId;
                    } else {
                        $shelfId = $value['shelf_id'];
                        $locationId = $value['location_id'];
                    }
                    $productInfo = MaterielsTypeModel::where([
                        'id' => $value['type_id']
                    ])->first();
                    if (!empty($productInfo['delete_flag'])) {
                        throw new Exception('换货商品：`' . $productInfo['materiel_name'] . '`的信息，不存在!');
                    }
                    $storageCond = [
                        'delete_flag' => 0,
                        'main_id' => $barterData['main_id'],
                        'type_id' => $value['type_id'],
                        'storage_id' => $value['storage_id']
                    ];
                    if (!empty($isUseShelf)) {
                        $storageCond['shelf_id'] = $shelfId;
                        $storageCond['location_id'] = $locationId;
                    }
                    $storageManageInfo = StorageManageModel::select(
                        'id',
                        'in_storage_num',
                        'alert_num',
                        'materiel_mean_cost'
                    )->where($storageCond)->first();
                    if (empty($storageManageInfo)) {
                        throw new Exception('商品:' . $productInfo['materiel_name'] . '的仓库' . $storageInfo['storage_name'] . '，没有库存信息！');
                    } else {
                        StorageManageModel::query()->where('id', $storageManageInfo['id'])
                            ->increment('virtual_storage_num', $value['num']);
                    }
                    if (empty($isUsePackagesComponents)) {//套餐是否与套件同步使用：0否，1是
                        if (!empty($productInfo['is_use_serial'])) {
                            if (!empty($value['serial_list'])) {
                                if (count($value['serial_list']) != $value['num']) {
                                    throw new Exception('换货商品：`' . $productInfo['materiel_name'] . '的序列号数量跟商品数量不相符！');
                                }
                                foreach ($value['serial_list'] as $sVal) {
                                    if (!empty($sVal['id'])) {
                                        $serialInfo = SerialNumberModel::where([
                                            'id' => $sVal['id'],
                                            'goods_id' => $value['type_id'],
                                            'delete_flag' => 0
                                        ])->first();

                                        if (!empty($serialInfo)) {
                                            if (!empty($serialInfo['status'])) {
                                                $serialData[] = [
                                                    'barter_id' => $barterId,
                                                    'serial_id' => $serialInfo['id'],
                                                    'serial_number' => $sVal['serial_no'],
                                                    'type_id' => $value['type_id'],
                                                    'main_id' => $barterData['main_id']
                                                ];

                                            } else {
                                                throw new Exception('换货商品：`' . $productInfo['materiel_name'] . '的序列号（' . $serialInfo['serial_no'] . '）已使用！');
                                            }
                                        } else {
                                            throw new Exception('换货商品：`' . $productInfo['materiel_name'] . '的序列号（' . $sVal['serial_no'] . '）不存在！');
                                        }
                                    } else {
                                        throw new Exception('换货商品：`' . $productInfo['materiel_name'] . '的序列号（' . $sVal['serial_no'] . '）不存在！');
                                    }
                                }
                            } else {
                                throw new Exception('请给换货商品：`' . $productInfo['materiel_name'] . ',选择序列号!');
                            }
                        }

                        if ($productInfo['is_product_materiel']) {
                            $productMaterielId[] = [
                                'id' => $productInfo['id'],
                                'product_use_tag' => 1
                            ];
                        }
                    }
                    $materielInfo[$key]['type_id'] = $value['type_id'];
                    $materielInfo[$key]['price'] = $value['price'];
                    $materielInfo[$key]['num'] = $value['num'];
                    $materielInfo[$key]['storage_id'] = $storageInfo['id'];
                    $materielInfo[$key]['main_id'] = $barterData['main_id'];
                    $materielInfo[$key]['barter_id'] = $barterId;
                    $materielInfo[$key]['created_at'] = $barterData['logTime'];
                    $money += ($value['price'] * $value['num']);
                    $materielInfo[$key]['shelf_id'] = $shelfId;
                    $materielInfo[$key]['location_id'] = $locationId;
                    $materielInfo[$key]['remark'] = $value['remark'] ?? '';
                    $materielInfo[$key]['batch_info'] = !empty($value['batch_info']) ? json_encode($value['batch_info']) : '';
                }
                BarterGoodsDetailModel::insert($materielInfo);
                if (!empty($serialData)) {
                    BarterOutSerialNumberModel::insert($serialData);
                }
            }
            if (!empty($barterData['barter_logistics_info'])) {//添加换货物流信息
                $logisticsData = [];
                $sellLogisticsInfo = json_decode($barterData['barter_logistics_info'], true);
                if (is_array($sellLogisticsInfo)) {
                    foreach ($sellLogisticsInfo as $lVal) {
                        if (!empty($lVal['logistics_company']) && empty($lVal['logistics_order_no'])) {
                            throw new Exception('物流公司名称：' . $lVal['logistics_company'] . '物流号不能为空');
                        }
                        if (empty($lVal['logistics_company']) && !empty($lVal['logistics_order_no'])) {
                            throw new Exception('物流号：' . $lVal['logistics_order_no'] . '物流公司名称不能为空');
                        }
                        $logisticsData[] = [
                            'barter_id' => $barterId,
                            'user_id' => $barterData['user_id'],
                            'main_id' => $barterData['main_id'],
                            'created_at' => $barterData['logTime'],
                            'logistics_company' => $lVal['logistics_company'],
                            'logistics_order_no' => $lVal['logistics_order_no']
                        ];
                    }
                    if (!empty($logisticsData)) {
                        BarterLogisticsInfoModel::insert($logisticsData);
                    }
                } else {
                    throw new Exception('换货物流信息异常');
                }
            }
            BarterModel::where('id', $barterId)->update([
                'money' => $money,
                'final_money' => $money
            ]);
            if (!empty($barterData['approver_id'])) {
                //审核列表
                CheckModel::insert([
                    'type' => 4,
                    'all_id' => $barterId,
                    'main_id' => $barterData['main_id'],
                    'user_id' => $barterData['user_id'],
                    'check_person' => $barterData['approver_id'],
                    'order_no' => $barterData['order_no'],
                    'created_at' => $barterData['logTime'],
                    'out_in_status' => 1,
                ]);
            }
            if (!empty($productMaterielId)) {
                batch()->update(new MaterielTypeModel, $productMaterielId, 'id');
            }

            $logData = '换货单号：' . $barterData['order_no'] . '创建成功!';
            CommonService::log('添加换货单', $barterData, $logData);
            DB::commit();//提交事务
            return ['code' => 0, 'msg' => 'success', 'data' => $barterId];
        } catch (Exception $e) {
            DB::rollBack();//事务回滚
            $returnId = SalesReturnModel::where([
                'barter_return_no' => $data['barter_return_no']
            ])->value('id');
            if (!empty($returnId)) {
                CheckModel::where([
                    'all_id' => $returnId,
                    'type' => 5
                ])->delete();
                SalesOutSerialNumberModel::where('return_id', $returnId)->delete();
                SalesReturnGoodsDetailModel::where('return_id', $returnId)->delete();
                SalesReturnModel::where('barter_return_no', $data['barter_return_no'])->delete();
            }
            Log::debug('添加换货单异常:' . var_export($e->getMessage(), true));
            //异常响应
            return ['code' => 1, 'msg' => $e->getMessage(), 'data' => ''];
        }
    }

    /**
     * 修改换货和退货
     * @param unknown $data
     * @param number $isUseShelf
     * @param number $isUsePackagesComponents
     * @return \Illuminate\Http\JsonResponse
     */
    static public function editReturnBarter($data, $isUseShelf = 0, $isShareShelfLocation, $isUsePackagesComponents = 0)
    {
        DB::beginTransaction();
        try {
            //修改退货
            $returnData = array_merge($data, $data['return_info']);
            unset($returnData['barter_info']);
            unset($returnData['barter_goods_info']);
            unset($returnData['barter_logistics_info']);
            $returnData['refund_date'] = strtotime($data['create_time']);
            self::editReturn($returnData, $isUseShelf = 0, $isShareShelfLocation, $isUsePackagesComponents = 0);

            //修改换货
            $barterData = array_merge($data, $data['barter_info']);
            unset($barterData['return_info']);
            unset($barterData['return_goods_info']);
            unset($barterData['return_logistics_info']);
            $barterData['barter_date'] = strtotime($data['create_time']);
            self::editBarter($barterData, $isUseShelf = 0, $isShareShelfLocation, $isUsePackagesComponents = 0);

            DB::commit();//提交事务
            return ['code' => 0, 'msg' => 'success', 'data' => ''];
        } catch (\Exception $e) {
            DB::rollBack();//事务回滚
            Log::debug('修改换货单异常:' . var_export($e->getMessage(), true));
            //异常响应
            return ['code' => 1, 'msg' => $e->getMessage(), 'data' => ''];
        }
    }

    /**
     * 修改换货
     * @param unknown $data
     * @param number $isUseShelf
     * @param number $isUsePackagesComponents
     * @return number
     * @throws Exception
     */
    static public function editBarter($data, $isUseShelf = 0, $isShareShelfLocation, $isUsePackagesComponents = 0)
    {
        $money = 0;//总金额
        $updData = [];
        $addData = [];
        $serialData = [];
        $materielInfo = [];
        $barterData = $data;
        $delBarterGoodsId = [];
        unset($data['logTime']);
        unset($data['return_id']);
        unset($data['barter_info']);
        unset($data['create_time']);
        unset($data['barter_goods_info']);
        unset($data['barter_logistics_info']);
        $barterInfo = BarterModel::select(
            'id',
            'order_no',
            'out_status'
        )->where('id', $data['barter_id'])->first();
        if (empty($barterInfo)) {
            throw new Exception('换货信息，没有找到！');
        }
        if (!empty($barterInfo['out_status'])) {
            throw new Exception('换货号：' . $barterInfo['order_no'] . '已出库，不能修改！');
        }
        $barterId = $barterInfo['id'];
        unset($data['barter_id']);
        BarterModel::where('id', $barterId)->update($data);
        if (!empty($barterData['barter_goods_info'])) {
            //商品详细添加
            $goodsInfo = json_decode($barterData['barter_goods_info'], true);
            foreach ($goodsInfo as $key => $value) {
                $delBarterSerialIdArr = [];
                //仓库信息
                $storageInfo = StorageModel::where([
                    'id' => $value['storage_id'],
                    'main_id' => $barterData['main_id'],
                    'delete_flag' => 0,
                ])->first();
                if (empty($storageInfo)) {
                    throw new Exception('换货仓库`' . $value['storage_name'] . '`不存在');
                }
                if (empty($value['shelf_id']) || empty($value['location_id'])) {
                    if (!empty($isShareShelfLocation)) {
                        throw new Exception('您开启强制选择货架及库位，请选择！');
                    }
                    $shelfId = 0;
                    $locationId = 0;
                    $sfData = ShelfService::get_default($value['storage_id']);
                    if (!empty($sfData)) {
                        $shelfId = $sfData['id'];
                        $lData = ShelfService::get_default($sfData['id'], 2);
                        $locationId = $lData['id'];
                    }
                    $value['shelf_id'] = $shelfId;
                    $value['location_id'] = $locationId;
                } else {
                    $shelfId = $value['shelf_id'];
                    $locationId = $value['location_id'];
                }
                $productInfo = MaterielsTypeModel::where([
                    'id' => $value['type_id']
                ])->first();
                if (!empty($productInfo['delete_flag'])) {
                    throw new Exception('换货商品：`' . $value['storage_name'] . '`的信息，不存在!');
                }
                if (empty($isUsePackagesComponents)) {//套餐是否与套件同步使用：0否，1是
                    if (!empty($productInfo['is_use_serial'])) {
                        if (!empty($value['serial_list'])) {
                            if (count($value['serial_list']) != $value['num']) {
                                throw new Exception('换货商品：`' . $productInfo['materiel_name'] . '的序列号数量跟商品数量不相符！');
                            }
                            foreach ($value['serial_list'] as $sVal) {
                                if (!empty($sVal['serial_no'])) {
                                    $serialInfo = SerialNumberModel::where([
                                        'serial_no' => $sVal['serial_no'],
                                        'goods_id' => $productInfo['id'],
                                        'main_id' => $data['main_id'],
                                        'delete_flag' => 0
                                    ])->first();
                                    if (!empty($serialInfo)) {
                                        if (!empty($serialInfo['status'])) {
                                            $serialData = [
                                                'barter_id' => $barterId,
                                                'serial_id' => $serialInfo['id'],
                                                'serial_number' => $sVal['serial_no'],
                                                'type_id' => $value['type_id'],
                                                'main_id' => $barterData['main_id'],
                                            ];
                                            if (!empty($sVal['barter_serial_id'])) {
                                                $serialData = array_merge($serialData, ['updated_at' => $barterData['logTime']]);
                                                BarterOutSerialNumberModel::where([
                                                    'id' => $sVal['barter_serial_id']
                                                ])->update($serialData);
                                                $delBarterSerialIdArr[] = $sVal['barter_serial_id'];
                                            } else {
                                                $serialData = array_merge(
                                                    $serialData,
                                                    ['created_at' => $barterData['logTime']
                                                    ]);
                                                $delBarterSerialIdArr[] = BarterOutSerialNumberModel::insertGetId($serialData);
                                            }
                                        } else {
                                            throw new Exception('换货商品：`' . $productInfo['materiel_name'] . '的序列号（' . $serialInfo['serial_no'] . '）已使用！');
                                        }
                                    } else {
                                        throw new Exception('换货商品：`' . $productInfo['materiel_name'] . '的序列号（' . $sVal['serial_no'] . '）不存在！');
                                    }
                                } else {
                                    throw new Exception('换货商品：`' . $productInfo['materiel_name'] . '的序列号（' . $sVal['serial_no'] . '）不存在！');
                                }
                            }
                        } else {
                            throw new Exception('请给换货商品：`' . $productInfo['materiel_name'] . ',选择序列号!');
                        }
                    }
                    if ($productInfo['is_product_materiel']) {
                        $productMaterielId[] = [
                            'id' => $productInfo['id'],
                            'product_use_tag' => 1
                        ];
                    }
                }

                $materielInfo = [];
                $money += ($value['price'] * $value['num']);
                $materielInfo['type_id'] = $value['type_id'];
                $materielInfo['price'] = $value['price'];
                $materielInfo['num'] = $value['num'];
                $materielInfo['storage_id'] = $storageInfo['id'];
                $materielInfo['main_id'] = $barterData['main_id'];
                $materielInfo['barter_id'] = $barterId;
                $materielInfo['shelf_id'] = $shelfId;
                $materielInfo['location_id'] = $locationId;
                $materielInfo['piece'] = empty($value['piece']) ? 0 : $value['piece'];
                $materielInfo['remark'] = $value['remark'] ?? '';
                $materielInfo['batch_info'] = !empty($value['batch_info']) ? json_encode($value['batch_info']) : '';
                if (!empty($value['barter_goods_id'])) {
                    $delBarterGoodsId[] = $value['barter_goods_id'];
                    $materielInfo['id'] = $value['barter_goods_id'];
                    $materielInfo = array_merge(
                        $materielInfo,
                        ['updated_at' => $barterData['logTime']]
                    );
                    $updData[] = $materielInfo;
                } else {
                    $materielInfo = array_merge(
                        $materielInfo,
                        ['created_at' => $barterData['logTime']]
                    );
                    $addData[] = $materielInfo;
                }

                if (!empty($delBarterSerialIdArr)) {
                    BarterOutSerialNumberModel::where([
                        'status' => 1,
                        'main_id' => $data['main_id'],
                        'type_id' => $value['type_id'],
                        'barter_id' => $barterInfo['id'],
                    ])->whereNotIn('id', $delBarterSerialIdArr)
                        ->update(['delete_flag' => 1]);
                } else {
                    BarterOutSerialNumberModel::where([
                        'status' => 1,
                        'main_id' => $data['main_id'],
                        'type_id' => $value['type_id'],
                        'barter_id' => $barterInfo['id'],
                    ])->update(['delete_flag' => 1]);
                }
            }
            if (!empty($updData)) {
                batch()->update(new BarterGoodsDetailModel(), $updData, 'id');
            }
            if (!empty($delBarterGoodsId)) {
                BarterGoodsDetailModel::where([
                    'main_id' => $data['main_id'],
                    'barter_id' => $barterInfo['id']
                ])->whereNotIn('id', $delBarterGoodsId)
                    ->update(['delete_flag' => 1]);
            } else {
                BarterGoodsDetailModel::where([
                    'main_id' => $data['main_id'],
                    'barter_id' => $barterInfo['id']
                ])->update(['delete_flag' => 1]);
            }
            if (!empty($addData)) {
                BarterGoodsDetailModel::insert($addData);
            }
        } else {
            BarterGoodsDetailModel::where('id', $barterId)->update(['delete_flag' => 1]);
        }

        if (!empty($barterData['barter_logistics_info'])) {//添加物流信息
            $barterLogisticsIdArr = [];
            $barterLogisticsInfo = json_decode($barterData['barter_logistics_info'], true);
            if (is_array($barterLogisticsInfo)) {
                foreach ($barterLogisticsInfo as $sVal) {
                    if (!empty($sVal['logistics_company']) && empty($sVal['logistics_order_no'])) {
                        throw new Exception('物流公司名称：' . $sVal['logistics_company'] . '物流号不能为空');

                    }
                    if (empty($sVal['logistics_company']) && !empty($sVal['logistics_order_no'])) {
                        throw new Exception('物流号：' . $sVal['logistics_order_no'] . '物流公司名称不能为空');
                    }
                    $logisticsData = [
                        'user_id' => $data['user_id'],
                        'main_id' => $data['main_id'],
                        'barter_id' => $barterId,
                        'logistics_company' => $sVal['logistics_company'],
                        'logistics_order_no' => $sVal['logistics_order_no'],
                    ];

                    if (!empty($sVal['id'])) {
                        $barterLogisticsIdArr[] = $sVal['id'];
                        $logisticsData = array_merge(
                            $logisticsData,
                            ['updated_at' => $barterData['logTime']
                            ]);
                        BarterLogisticsInfoModel::where('id', $sVal['id'])->update($logisticsData);
                    } else {
                        $logisticsData = array_merge(
                            $logisticsData,
                            ['created_at' => $barterData['logTime']
                            ]);
                        $id = BarterLogisticsInfoModel::insert($logisticsData);
                        $barterLogisticsIdArr[] = $id;
                    }
                }
                if (!empty($returnLogisticsIdArr)) {
                    BarterLogisticsInfoModel::whereNotIn('id', $barterLogisticsIdArr)->update(['delete_flag' => 1]);
                }
            } else {
                throw new Exception('换货物流信息异常');
            }
        }
        BarterModel::where('id', $barterId)->update(['money' => $money]);

        //审核列表
        /* if(!empty($data['approver_id'])){
             CheckModel::where([
                 'id'=>$data['main_id'],
                 'type'=>4,
                 'all_id'=>$barterId
             ])->update([
                 'check_person'=>$data['approver_id'],
             ]);
         }*/
        if (!empty($productMaterielId)) {
            batch()->update(new MaterielTypeModel, $productMaterielId, 'id');
        }
        $logData = '换货单号：' . $barterInfo['order_no'] . '的信息已修改!';
        CommonService::log('修改换货单', $barterData, $logData);
    }

    /**
     * 退货单
     * @param unknown $data
     * @return number
     */
    static public function addReturn($data, $isUseShelf = 0, $isShareShelfLocation, $isUsePackagesComponents = 0)
    {
        DB::beginTransaction();
        try {
            $money = 0;//货款金额
            $serialData = [];
            $salesMaterielInfo = [];
            $salesPackageInfo = [];
            $returnData = $data;
            unset($data['logTime']);
            unset($data['return_info']);
            unset($data['create_time']);
            unset($data['spread_price']);
            unset($data['return_goods_info']);
            unset($data['return_logistics_info']);
            $returnId = SalesReturnModel::insertGetId($data);//创建销售主单信息
            if (!empty($returnData['return_goods_info'])) {
                $goodsInfo = json_decode($returnData['return_goods_info'], true);//商品详细添加
                foreach ($goodsInfo as $key => $value) {
                    if (empty($value['shelf_id']) || empty($value['location_id'])) {
                        if (!empty($isShareShelfLocation)) {
                            throw new Exception('您开启强制选择货架及库位，请选择！');
                        }
                        $sfData = ShelfService::get_default($value['storage_id']);
                        if (!empty($sfData)) {
                            $shelfId = $sfData['id'];
                            $lData = ShelfService::get_default($shelfId, 2);
                            $locationId = $lData['id'];
                        } else {
                            $shelfId = 0;
                            $locationId = 0;
                            $value['shelf_id'] = 0;
                            $value['location_id'] = 0;
                        }
                    } else {
                        $shelfId = $value['shelf_id'];
                        $locationId = $value['location_id'];
                    }
                    $materielInfo = MaterielsTypeModel::where([
                        'id' => $value['type_id']
                    ])->first();

                    if (!empty($materielInfo['delete_flag'])) {
                        throw new Exception('退货商品：' . $materielInfo['materiel_name'] . '不存在！');
                    }
                    $money += ($value['cost'] * $value['return_num']);
                    $storageInfo = StorageModel::where('id', $value['storage_id'])->first();
                    if (!empty($storageInfo['delete_flag'])) {
                        throw new Exception('退货仓库：' . $materielInfo['storage_name'] . '不存在！');
                    }
                    if (empty($isUsePackagesComponents)) {//套餐是否与套件同步使用：0否，1是
                        if (!empty($materielInfo['is_use_serial'])) {
                            if (!empty($value['serial_list'])) {
                                $serialList = explode(',', $value['serial_list']);
                                if (is_array($serialList)) {
                                    if (count($serialList) != $value['return_num']) {
                                        throw new Exception('退货商品：`' . $materielInfo['materiel_name'] . '的序列号数量跟商品退货数量不相符！');
                                    }
                                    foreach ($serialList as $sKey => $sVal) {
                                        $serialInfo = SerialNumberModel::where([
                                            'serial_no' => $sVal,
                                            'goods_id' => $materielInfo['type_id'],
                                            'main_id' => $data['main_id'],
                                            'delete_flag' => 0
                                        ])->first();
                                        if (!empty($serialInfo)) {
                                            throw new Exception('退货商品：`' . $materielInfo['materiel_name'] . '的序列号（' . $sVal . '）已存在！');
                                        }
                                        $serialData[] = [
                                            'serial_number' => $sVal,
                                            'type_id' => $materielInfo['id'],
                                            'main_id' => $data['main_id'],
                                            'return_id' => $returnId,
                                            'created_at' => $returnData['logTime']
                                        ];
                                    }

                                } else {
                                    throw new Exception('退货商品：`' . $materielInfo['materiel_name'] . ',序列号数据异常!');
                                }
                            } else {
                                throw new Exception('请给退货商品：`' . $materielInfo['materiel_name'] . ',选择序列号!');
                            }
                        }
                    }
                    $salesMaterielInfo[$key]['materiel_type_id'] = $value['type_id'];
                    $salesMaterielInfo[$key]['name'] = $materielInfo['materiel_name'];
                    $salesMaterielInfo[$key]['type_name'] = $materielInfo['type_name'];
                    $salesMaterielInfo[$key]['materiel_no'] = $materielInfo['materiel_no'];
                    $salesMaterielInfo[$key]['price'] = $materielInfo['selling_price'];
                    $salesMaterielInfo[$key]['cost_price'] = $value['cost'];
                    $salesMaterielInfo[$key]['return_id'] = $returnId;
                    $salesMaterielInfo[$key]['num'] = $value['return_num'];
                    $salesMaterielInfo[$key]['image'] = $materielInfo['materiel_img'];
                    $salesMaterielInfo[$key]['warehouse_id'] = $storageInfo['id'];
                    $salesMaterielInfo[$key]['warehouse'] = $storageInfo['storage_name'];
                    $salesMaterielInfo[$key]['main_id'] = $data['main_id'];
                    $salesMaterielInfo[$key]['created_at'] = time();
                    $salesMaterielInfo[$key]['shelf_id'] = $shelfId;
                    $salesMaterielInfo[$key]['location_id'] = $locationId;
                    $salesMaterielInfo[$key]['remark'] = $value['remark'] ?? '';
                    $salesMaterielInfo[$key]['batch_info'] = !empty($value['batch_info']) ? json_encode($value['batch_info']) : '';

                }
                SalesReturnGoodsDetailModel::insert($salesMaterielInfo);

                if (!empty($serialData)) {
                    SalesOutSerialNumberModel::insert($serialData);
                }
            }
            if (!empty($returnData['return_logistics_info'])) {//添加退货物流信息

                $sellLogisticsInfo = json_decode($returnData['return_logistics_info'], true);
                if (is_array($sellLogisticsInfo)) {
                    $logisticsData = [];
                    foreach ($sellLogisticsInfo as $lVal) {
                        if (!empty($lVal['logistics_company']) && empty($lVal['logistics_order_no'])) {
                            throw new Exception('物流公司名称：' . $lVal['logistics_company'] . '物流号不能为空');
                        }
                        if (empty($lVal['logistics_company']) && !empty($lVal['logistics_order_no'])) {
                            throw new Exception('物流号：' . $lVal['logistics_order_no'] . '物流公司名称不能为空');
                        }
                        $logisticsData[] = [
                            'return_id' => $returnId,
                            'user_id' => $returnData['user_id'],
                            'main_id' => $returnData['main_id'],
                            'created_at' => $returnData['logTime'],
                            'logistics_company' => $lVal['logistics_company'],
                            'logistics_order_no' => $lVal['logistics_order_no']
                        ];
                    }
                    if (!empty($logisticsData)) {
                        SalesReturnLogisticsInfoModel::insert($logisticsData);
                    }
                } else {
                    throw new Exception('退货物流信息异常');
                }
            }
            if (!empty($data['approver_id'])) {
                //审核列表
                CheckModel::insert([
                    'type' => 5,
                    'all_id' => $returnId,
                    'main_id' => $data['main_id'],
                    'user_id' => $data['user_id'],
                    'check_person' => $data['approver_id'],
                    'order_no' => $data['order_no'],
                    'out_in_status' => 1,
                    'created_at' => $returnData['logTime'],
                ]);
            }
            SalesReturnModel::where('id', $returnId)->update([
                'final_money' => $money,
                'money' => $money
            ]);
            $logData = '退货单号：' . $returnData['order_no'] . '创建成功!';
            CommonService::log('添加退货单', $returnData, $logData);
            DB::commit();//提交事务
            return ['code' => 0, 'msg' => 'success', 'data' => ''];
        } catch (\Exception $e) {
            DB::rollBack();//事务回滚
            Log::debug('添加退货单' . var_export($e->getMessage(), true));
            //异常响应
            return ['code' => 1, 'msg' => $e->getMessage(), 'data' => ''];
        }
    }

    /**
     * 修改退货单
     * @param unknown $data
     * @return number
     */
    static public function editReturn($data, $isUseShelf = 0, $isShareShelfLocation, $isUsePackagesComponents = 0)
    {
        $money = 0;//总金额
        $updData = [];
        $addData = [];
        $serialData = [];
        $returnData = $data;
        $delReturnGoodsId = [];

        $salesMaterielInfo = [];
        unset($data['logTime']);
        unset($data['barter_id']);
        unset($data['create_time']);
        unset($data['return_info']);
        unset($data['spread_price']);
        unset($data['return_goods_info']);
        unset($data['return_logistics_info']);
        $returnInfo = SalesReturnModel::select(
            'id',
            'order_no',
            'out_status'
        )->where('id', $data['return_id'])->first();
        if (empty($returnInfo)) {
            throw new Exception('退货信息，没有找到！');
        }
        if (!empty($returnInfo['out_status'])) {
            throw new Exception('退货号：' . $returnInfo['order_no'] . '已出库，不能修改！');
        }
        $returnId = $returnInfo['id'];
        unset($data['return_id']);
        SalesReturnModel::where('id', $returnId)->update($data);
        if (!empty($returnData['return_goods_info'])) {
            //商品详细添加
            $goodsInfo = json_decode($returnData['return_goods_info'], true);
            foreach ($goodsInfo as $key => $value) {
                $delReturnSerialIdArr = [];
                //仓库信息
                $storageInfo = StorageModel::where([
                    'id' => $value['storage_id'],
                    'main_id' => $data['main_id'],
                    'delete_flag' => 0,
                ])->first();
                if (empty($storageInfo)) {
                    throw new Exception('退货仓库`' . $value['storage_name'] . '`不存在');
                }
                if (empty($value['shelf_id']) || empty($value['location_id'])) {
                    if (!empty($isShareShelfLocation)) {
                        throw new Exception('您开启强制选择货架及库位，请选择！');
                    }
                    $shelfId = 0;
                    $locationId = 0;
                    $sfData = ShelfService::get_default($value['storage_id']);
                    if (!empty($sfData)) {
                        $shelfId = $sfData['id'];
                        $lData = ShelfService::get_default($sfData['id'], 2);
                        $locationId = $lData['id'];
                    }
                    $value['shelf_id'] = $shelfId;
                    $value['location_id'] = $locationId;
                } else {
                    $shelfId = $value['shelf_id'];
                    $locationId = $value['location_id'];
                }
                $productInfo = MaterielsTypeModel::where([
                    'id' => $value['type_id']
                ])->first();
                if (!empty($productInfo['delete_flag'])) {
                    throw new Exception('退货商品：`' . $value['storage_name'] . '`的信息，不存在!');
                }
                if (empty($isUsePackagesComponents)) {//套餐是否与套件同步使用：0否，1是
                    if (!empty($productInfo['is_use_serial'])) {
                        if (!empty($value['serial_list'])) {
                            if (count($value['serial_list']) != $value['return_num']) {
                                throw new Exception('退货商品：`' . $productInfo['materiel_name'] . '的序列号数量跟商品退货数量不相符！');
                            }
                            foreach ($value['serial_list'] as $sKey => $sVal) {
                                if (empty($sVal['return_serial_id'])) {
                                    $serialInfo = SerialNumberModel::where([
                                        'serial_no' => $sVal['serial_no'],
                                        'goods_id' => $productInfo['id'],
                                        'main_id' => $data['main_id'],
                                        'delete_flag' => 0
                                    ])->first();
                                    if (!empty($serialInfo)) {
                                        throw new Exception('退货商品：`' . $productInfo['materiel_name'] . '的序列号（' . $sVal['serial_no'] . '）已存在！');
                                    }
                                }
                                $serialData = [
                                    'serial_number' => $sVal['serial_no'],
                                    'type_id' => $productInfo['id'],
                                    'main_id' => $data['main_id'],
                                    'return_id' => $returnId
                                ];

                                if (!empty($sVal['return_serial_id'])) {
                                    $serialData = array_merge(
                                        $serialData,
                                        ['updated_at' => $returnData['logTime']
                                        ]);
                                    SalesOutSerialNumberModel::where([
                                        'id' => $sVal['return_serial_id']
                                    ])->update($serialData);
                                    $delReturnSerialIdArr[] = $sVal['return_serial_id'];
                                } else {
                                    $serialData = array_merge(
                                        $serialData,
                                        ['created_at' => $returnData['logTime']
                                        ]);
                                    $delReturnSerialIdArr[] = SalesOutSerialNumberModel::insertGetId($serialData);
                                }
                            }

                        } else {
                            throw new Exception('请给退货商品：`' . $productInfo['materiel_name'] . ',选择序列号!');
                        }
                    }
                    if ($productInfo['is_product_materiel']) {
                        $productMaterielId[] = [
                            'id' => $productInfo['id'],
                            'product_use_tag' => 1
                        ];
                    }
                }
                $salesMaterielInfo = [];
                $money += ($value['cost'] * $value['return_num']);
                $salesMaterielInfo['materiel_type_id'] = $value['type_id'];
                $salesMaterielInfo['name'] = $productInfo['materiel_name'];
                $salesMaterielInfo['type_name'] = $productInfo['type_name'];
                $salesMaterielInfo['materiel_no'] = $productInfo['materiel_no'];
                $salesMaterielInfo['price'] = $productInfo['selling_price'];
                $salesMaterielInfo['cost_price'] = $value['cost'];
                $salesMaterielInfo['return_id'] = $returnId;
                $salesMaterielInfo['num'] = $value['return_num'];
                $salesMaterielInfo['image'] = $productInfo['materiel_img'];
                $salesMaterielInfo['warehouse_id'] = $storageInfo['id'];
                $salesMaterielInfo['warehouse'] = $storageInfo['storage_name'];
                $salesMaterielInfo['main_id'] = $data['main_id'];
                $salesMaterielInfo['shelf_id'] = $shelfId;
                $salesMaterielInfo['location_id'] = $locationId;
                $salesMaterielInfo['remark'] = $value['remark'] ?? '';
                $salesMaterielInfo['batch_info'] = !empty($value['batch_info']) ? json_encode($value['batch_info']) : '';

                if (!empty($value['return_goods_id'])) {
                    $delReturnGoodsId[] = $value['return_goods_id'];
                    $salesMaterielInfo['id'] = $value['return_goods_id'];
                    $salesMaterielInfo = array_merge(
                        $salesMaterielInfo,
                        ['updated_at' => $returnData['logTime']]
                    );
                    $updData[] = $salesMaterielInfo;

                } else {
                    $salesMaterielInfo = array_merge(
                        $salesMaterielInfo,
                        ['created_at' => $returnData['logTime']]
                    );
                    $addData[] = $salesMaterielInfo;
                }

                if (!empty($delReturnSerialIdArr)) {
                    SalesOutSerialNumberModel::where([
                        'status' => 1,
                        'main_id' => $data['main_id'],
                        'type_id' => $value['type_id'],
                        'return_id' => $returnInfo['id'],
                    ])->whereNotIn('id', $delReturnSerialIdArr)
                        ->update(['delete_flag' => 1]);
                } else {
                    SalesOutSerialNumberModel::where([
                        'status' => 1,
                        'main_id' => $data['main_id'],
                        'type_id' => $value['type_id'],
                        'return_id' => $returnInfo['id'],
                    ])->update(['delete_flag' => 1]);
                }
            }
            if (!empty($updData)) {
                batch()->update(new SalesReturnGoodsDetailModel(), $updData, 'id');
            }
            if (!empty($delReturnGoodsId)) {
                SalesReturnGoodsDetailModel::where([
                    'main_id' => $data['main_id'],
                    'return_id' => $returnInfo['id']
                ])->whereNotIn('id', $delReturnGoodsId)
                    ->update(['delete_flag' => 1]);
            } else {
                SalesReturnGoodsDetailModel::where([
                    'main_id' => $data['main_id'],
                    'return_id' => $returnInfo['id']
                ])->update(['delete_flag' => 1]);
            }
            if (!empty($addData)) {
                SalesReturnGoodsDetailModel::insert($addData);
            }
        } else {
            throw new Exception('退货商品必须选择');
        }

        if (!empty($returnData['return_logistics_info'])) {//添加物流信息
            $returnLogisticsIdArr = [];
            $returnLogisticsInfo = json_decode($returnData['return_logistics_info'], true);
            if (is_array($returnLogisticsInfo)) {
                foreach ($returnLogisticsInfo as $sVal) {
                    if (!empty($sVal['logistics_company']) && empty($sVal['logistics_order_no'])) {
                        throw new Exception('物流公司名称：' . $sVal['logistics_company'] . '物流号不能为空');
                    }
                    if (empty($sVal['logistics_company']) && !empty($sVal['logistics_order_no'])) {
                        throw new Exception('物流号：' . $sVal['logistics_order_no'] . '物流公司名称不能为空');
                    }
                    $logisticsData = [
                        'user_id' => $data['user_id'],
                        'main_id' => $data['main_id'],
                        'return_id' => $returnId,
                        'logistics_company' => $sVal['logistics_company'],
                        'logistics_order_no' => $sVal['logistics_order_no'],
                    ];
                    if (!empty($sVal['id'])) {
                        $logisticsData = array_merge(
                            $logisticsData,
                            ['updated_at' => $returnData['logTime']
                            ]);
                        SalesReturnLogisticsInfoModel::where('id', $sVal['id'])->update($logisticsData);
                        $returnLogisticsIdArr[] = $sVal['id'];
                    } else {
                        $logisticsData = array_merge(
                            $logisticsData,
                            ['created_at' => $returnData['logTime']
                            ]);
                        $id = SalesReturnLogisticsInfoModel::insertGetId($logisticsData);
                        $returnLogisticsIdArr[] = $id;
                    }
                }
                if (!empty($returnLogisticsIdArr)) {
                    SalesReturnLogisticsInfoModel::whereNotIn('id', $returnLogisticsIdArr)->update(['delete_flag' => 1]);
                }
            } else {
                throw new Exception('退货物流信息异常');
            }
        }

        //审核列表
        /* if(!empty($data['approver_id'])){
             CheckModel::where([
                 'main_id'=>$data['main_id'],
                 'type'=>5,
                 'all_id'=>$returnId
             ])->update([
                 'check_person'=>$data['approver_id'],
                 'out_in_status'=>1
             ]);
         }*/
        SalesReturnModel::where('id', $returnId)->update(['money' => $money]);
        //审核列表
        $logData = '退货单号：' . $returnInfo['order_no'] . '的信息已修改!';
        CommonService::log('修改退货单', $returnData, $logData);
    }

    public static function barterReturnList(array $userId, array $data)
    {
        $data['sales_return_idArr'] = [];
        if (!empty($data['keyword']) && !empty($data['search_type'])) {//关键词搜索组是否启用
            $returnList = SalesReturnModel::select('id')
                ->where([
                    'delete_flag' => 0,
                    'main_id' => $data['main_id'],
                    ['barter_return_no', '!=', '']
                ])->get()->toArray();
            if (!empty($returnList)) {
                $data['sales_return_idArr'] = array_column($returnList, 'id');
            }
            switch ($data['search_type']) {
                case 1://1->商品名称;
                case 2://2->商品编号
                    $result = self::searchGoodsInfo($userId, $data);
                    break;
                case 3://搜索内部单号
                case 4://搜索外部单号
                case 5://搜索发货人姓名
                case 6://搜索发货人姓名
                    $result = self::searchBarterList($userId, $data);
                    break;
                case 7://搜索快递单号
                    $result = SELF::searchExpressNo($userId, $data);
                    break;
                case 8://搜索司机姓名
                    $result = SELF::searchDriverName($userId, $data);
                    break;
            }
        } else {
            $result = SELF::searchWithoutKeyword($userId, $data);
        }
        return $result;
    }

    //商品信息搜索
    static private function searchGoodsInfo($userId, $data)
    {
        $barterGoodsInfo = BarterGoodsDetailModel::getGoodsDetailInfo($userId, $data);

        $returnGoodsInfo = SalesReturnGoodsDetailModel::getBarterReturnGoodsDetailInfo($userId, $data);

        return SELF::barterReturnKeyWordList($returnGoodsInfo, $barterGoodsInfo, $userId, $data);
    }

    //根据请求参数搜索换货信息
    static private function searchBarterList($userId, $data)
    {
        $barterIdArr = [];
        $barterList = BarterModel::getBarterList($userId, $data);
        $returnList = SalesReturnModel::getBarterReturnList($userId, $data);
        return SELF::barterReturnKeyWordList($returnList, $barterList, $userId, $data);
    }

    //快递单号检索
    static private function searchExpressNo($userId, $data)
    {
        $barterIdArr = [];
        $BarterLogisticsList = BarterLogisticsInfoModel::getBarterLogisticsInfo($userId);
        $returnLogisticsList = SalesReturnLogisticsInfoModel::getReturnLogisticsInfo($userId);
        if (!empty($BarterLogisticsList)) {
            foreach ($BarterLogisticsList as $lVal) {
                if (!empty($lVal['logistics_order_no'])) {
                    $logisticsNoArr = explode(',', $lVal['logistics_order_no']);
                    if (!empty($logisticsNoArr)) {
                        foreach ($logisticsNoArr as $nVal) {
                            if (strpos($data['keyword'], $nVal) !== false) {
                                $barterIdArr[] = $lVal['barter_id'];
                            }
                        }
                    }
                }
            }
        }
        if (!empty($returnLogisticsList)) {
            foreach ($returnLogisticsList as $rVal) {
                if (!empty($rVal['logistics_order_no'])) {
                    $logisticsNoArr = explode(',', $rVal['logistics_order_no']);
                    if (!empty($logisticsNoArr)) {
                        foreach ($logisticsNoArr as $sVal) {
                            if (strpos($data['keyword'], $sVal) !== false) {
                                $barterIdArr[] = $rVal['barter_id'];
                            }
                        }
                    }
                }
            }
        }
        return self::commonSearchWithKeyword($userId, $data, array_unique($barterIdArr));
    }

    //搜索司机姓名
    static private function searchDriverName($userId, $data)
    {
        $barterIdArr = [];
        $driverList = BarterDriverModel::getBarterDriver($userId, $data);
        if (!empty($driverList)) {
            $barterIdArr = array_unique(array_column($driverList, 'barter_id'));
        }
        return self::commonSearchWithKeyword($userId, $data, $barterIdArr);
    }

    //使用关键词检索
    static private function commonSearchWithKeyword($userId, $data, $barterIdArr = [], $barterGoodsIdArr = [])
    {
        if ($data['user_id'] == $data['main_id']) {
            $condition['a.main_id'] = ['EQ' => $data['main_id']];
        } else {
            $condition['a.user_id'] = ['EQ' => $data['user_id']];
        }
        $query = BarterModel::select(
            'a.*',
            'b.username',
            'b.nickname',
            'e.nickname as approver_name',
            'd.expend',
            'd.collection_time',
            'd.collection_account',
            'd.money_flag',
            'a.id as barter_id',
            'c.id as return_id',
            'c.out_status as in_status',
            'c.consignee as return_consignee',
            'c.phone as return_consignee_phone',
            'c.address as return_consignee_address',
            'c.money as return_money',
            'c.order_no as return_order_no',
            'c.deliver_goods_type as return_deliver_goods_type',
            'c.transport_type as return_transport_type',
            'c.deliver_time as return_deliver_time',
            'c.remark as ret_remark'
        )->from('barter as a')
            ->leftJoin('admin as b', 'b.id', '=', 'a.user_id')
            ->leftJoin('admin as e', 'e.id', '=', 'a.approver_id')
            ->leftJoin('sales_return as c', 'c.barter_return_no', '=', 'a.barter_return_no')
            ->leftJoin('barter_pay_record as d', 'd.barter_id', '=', 'a.id')
            ->with('barterGoodsDetailInfo', function ($query) use ($barterGoodsIdArr) {
                $query->select(
                    'barter_goods_detail.id as barter_goods_id',
                    'a.materiel_name',
                    'a.type_name',
                    'a.materiel_no',
                    'a.materiel_img',
                    'a.materiel_unit',
                    'price',
                    'barter_goods_detail.num',
                    'barter_goods_detail.out_num',
                    'b.storage_name',
                    'b.id as storage_id',
                    'piece',
                    'barter_goods_detail.type_id',
                    'barter_goods_detail.barter_id',
                    'cost_price',
                    'barter_goods_detail.remark',
                    'barter_goods_detail.shelf_id',
                    'barter_goods_detail.location_id',
                    'se.shelf_name',
                    'lo.location_name',
                    'a.is_product_materiel'
                )->where([
                    'se.status' => 1,
                    'lo.status' => 1,
                    'a.delete_flag' => 0,
                    'b.delete_flag' => 0,
                    'barter_goods_detail.delete_flag' => 0,
                ])
                    ->leftJoin('materiel_type as a', 'a.id', '=', 'barter_goods_detail.type_id')
                    ->leftJoin('storage as b', 'b.id', '=', 'barter_goods_detail.storage_id')
                    ->leftJoin('storage_shelf as se', 'barter_goods_detail.shelf_id', '=', 'se.id')
                    ->leftJoin('storage_shelf_location as lo', 'barter_goods_detail.location_id', '=', 'lo.id');
            })->with('driverInfo', function ($query) {
                $query->select(
                    'id',
                    'plate_number',
                    'name',
                    'phone',
                    'logistics_company',
                    'remark',
                    'plate_image',
                    'id_card_image',
                    'driving_licence',
                    'barter_id'
                );
            })
            ->where([
                'a.delete_flag' => 0,
                'a.repeal_status' => $data['repeal_status']
            ])->where($condition);

        if (!empty($data['start_time'])) {
            $startTimeArr = explode(' ', $data['start_time']);
            $startTime = strtotime($startTimeArr[0] . ' 00:00:00');
        }

        if (!empty($data['end_time'])) {
            $endTimeArr = explode(' ', $data['end_time']);
            $endTime = strtotime($endTimeArr[0] . ' 23:59:59');
        }

        if (!empty($startTime) && !empty($endTime)) {
            $query->whereBetween('a.barter_date', [$startTime, $endTime]);
        } else if (!empty($startTime) && empty($endTime)) {
            $query->where('a.barter_date', '>=', $startTime);
        } else if (empty($startTime) && !empty($endTime)) {
            $query->where('a.barter_date', '<=', $endTime);
        }
        //换货状态
        switch ($data['status']) {
            //未收款未换货
            case 1:
                $query->where('a.pay_status', 0);
                $query->where('a.out_status', 0);
                break;
            //已收款
            case 2:
                $query->where('a.pay_status', 0);
                $query->where('a.out_status', 2);
                break;
            //已完结
            case 3:
                $query->where('a.out_status', 2);
                $query->where('a.pay_status', 2);
                break;
        }
        $query = $query->whereIn('a.id', $barterIdArr)
            ->orderBy('a.id', 'desc');
        if (!empty($data['currentPage'])) {
            $query = $query->paginate($data['pageSize'], ['*'], '', $data['currentPage'])->toArray();
        } else {
            $query = $query->get()->toArray();
            $query['data'] = $query;
        }
        if (!empty($query['data'])) {
            foreach ($query['data'] as &$value) {
                foreach ($value['barter_goods_detail_info'] as $k => $val) {
                    $storageManageInfo = StorageManageModel::select(
                        'id',
                        'in_storage_num'
                    )->where([
                        'shelf_id' => $val['shelf_id'],
                        'location_id' => $val['location_id'],
                        'type_id' => $val['type_id'],
                        'storage_id' => $val['storage_id'],
                        'delete_flag' => 0
                    ])->first();
                    $val['storage_manage_id'] = $storageManageInfo['id'] ?? '';
                    $val['in_storage_num'] = $storageManageInfo['in_storage_num'] ?? 0;
                }
                $value['return_goods_detail_info'] = [];
                if (!empty($value['return_id'])) {
                    $returnGoodsDetail = SalesReturnGoodsDetailModel::select(
                        'a.id as return_goods_id',
                        'c.materiel_name',
                        'c.type_name',
                        'c.materiel_no',
                        'c.materiel_img',
                        'c.materiel_unit',
                        'price',
                        'a.num',
                        'a.in_num',
                        'b.storage_name',
                        'b.id as storage_id',
                        'return_id',
                        'cost_price',
                        'a.remark',
                        'a.materiel_type_id as type_id',
                        'a.shelf_id',
                        'a.location_id',
                        'se.shelf_name',
                        'lo.location_name',
                        'c.is_product_materiel'
                    )->from('sales_return_goods_detail as a')
                        ->leftJoin('materiel_type as c', 'c.id', '=', 'a.materiel_type_id')
                        ->leftJoin('storage as b', 'b.id', '=', 'a.warehouse_id')
                        ->leftJoin('storage_shelf as se', 'a.shelf_id', '=', 'se.id')
                        ->leftJoin('storage_shelf_location as lo', 'a.location_id', '=', 'lo.id')
                        ->where([
                            'se.status' => 1,
                            'lo.status' => 1,
                            'a.delete_flag' => 0,
                            'b.delete_flag' => 0,
                            'c.delete_flag' => 0,
                            'a.main_id' => $data['main_id'],
                            'return_id' => $value['return_id'],
                        ])->get()->toArray();
                    if (!empty($returnGoodsDetail)) {
                        foreach ($returnGoodsDetail as &$rVal) {
                            $storageManageInfo = StorageManageModel::select(
                                'id',
                                'in_storage_num'
                            )->where([
                                'shelf_id' => $rVal['shelf_id'],
                                'location_id' => $rVal['location_id'],
                                'type_id' => $rVal['type_id'],
                                'storage_id' => $rVal['storage_id'],
                                'delete_flag' => 0
                            ])->first();
                            $rVal['storage_manage_id'] = $storageManageInfo['id'] ?? '';
                            $rVal['in_storage_num'] = $storageManageInfo['in_storage_num'] ?? 0;
                        }
                    }
                    $value['return_goods_detail_info'] = $returnGoodsDetail ?? [];
                }

                $value['customer_phone'] = '';
                if (!empty($value['customer_id'])) {
                    $value['customer_phone'] = SupplierCustomerModel::query()
                        ->where('id', $value['customer_id'])->value('phone') ?? '';
                }
            }
        }
        if (empty($data['currentPage'])) {
            $query = $query['data'];
        }
        return $query;
    }

    static private function searchWithoutKeyword($userId, $data)
    {
        if ($data['user_id'] == $data['main_id']) {
            $condition['a.main_id'] = ['EQ' => $data['main_id']];
        } else {
            $condition['a.user_id'] = ['EQ' => $data['user_id']];
        }
        $query = BarterModel::select(
            'a.*',
            'b.username',
            'b.nickname',
            'e.nickname as approver_name',
            'd.expend',
            'd.collection_time',
            'd.collection_account',
            'd.money_flag',
            'a.id as barter_id',
            'c.id as return_id',
            'c.out_status as in_status',
            'c.consignee as return_consignee',
            'c.phone as return_consignee_phone',
            'c.address as return_consignee_address',
            'c.money as return_money',
            'c.order_no as return_order_no',
            'c.deliver_goods_type as return_deliver_goods_type',
            'c.transport_type as return_transport_type',
            'c.deliver_time as return_deliver_time',
            'c.remark as ret_remark'
        )->from('barter as a')
            ->leftJoin('admin as b', 'b.id', '=', 'a.user_id')
            ->leftJoin('admin as e', 'e.id', '=', 'a.approver_id')
            ->leftJoin('sales_return as c', 'c.barter_return_no', '=', 'a.barter_return_no')
            ->leftJoin('barter_pay_record as d', 'd.barter_id', '=', 'a.id')
            ->with('barterGoodsDetailInfo', function ($query) {
                $query->select(
                    'barter_goods_detail.id as barter_goods_id',
                    'a.materiel_name',
                    'a.type_name',
                    'a.materiel_no',
                    'a.materiel_img',
                    'a.materiel_unit',
                    'price',
                    'barter_goods_detail.num',
                    'barter_goods_detail.out_num',
                    'b.storage_name',
                    'b.id as storage_id',
                    'piece',
                    'barter_id',
                    'cost_price',
                    'barter_goods_detail.remark',
                    'barter_goods_detail.type_id',
                    'barter_goods_detail.shelf_id',
                    'barter_goods_detail.location_id',
                    'se.shelf_name',
                    'lo.location_name',
                    'a.is_product_materiel'
                )->where([
                    'se.status' => 1,
                    'lo.status' => 1,
                    'a.delete_flag' => 0,
                    'b.delete_flag' => 0,
                    'barter_goods_detail.delete_flag' => 0
                ])
                    ->leftJoin('materiel_type as a', 'a.id', '=', 'barter_goods_detail.type_id')
                    ->leftJoin('storage as b', 'b.id', '=', 'barter_goods_detail.storage_id')
                    ->leftJoin('storage_shelf as se', 'barter_goods_detail.shelf_id', '=', 'se.id')
                    ->leftJoin('storage_shelf_location as lo', 'barter_goods_detail.location_id', '=', 'lo.id');
            })->with('driverInfo', function ($query) {
                $query->select(
                    'id',
                    'plate_number',
                    'name',
                    'phone',
                    'logistics_company',
                    'remark',
                    'plate_image',
                    'id_card_image',
                    'driving_licence',
                    'barter_id'
                );
            })
            ->where([
                'a.delete_flag' => 0,
                'a.repeal_status' => $data['repeal_status']
            ])->where($condition);
        if (!empty($data['start_time'])) {
            $startTimeArr = explode(' ', $data['start_time']);
            $startTime = strtotime($startTimeArr[0] . ' 00:00:00');
        }
        if (!empty($data['end_time'])) {
            $endTimeArr = explode(' ', $data['end_time']);
            $endTime = strtotime($endTimeArr[0] . ' 23:59:59');
        }
        if (!empty($startTime) && !empty($endTime)) {
            $query->whereBetween('a.barter_date', [$startTime, $endTime]);
        } else if (!empty($startTime) && empty($endTime)) {
            $query->where('a.barter_date', '>=', $startTime);
        } else if (empty($startTime) && !empty($endTime)) {
            $query->where('a.barter_date', '<=', $endTime);
        }
        //销售单状态
        switch ($data['status']) {
            //未收款未换货
            case 1:
                $query->where('a.pay_status', 0);
                $query->where('a.out_status', 0);
                break;
            //已收款
            case 2:
                $query->where('a.pay_status', 0);
                $query->where('a.out_status', 2);
                break;
            //已完结
            case 3:
                $query->where('a.out_status', 2);
                $query->where('a.pay_status', 2);
                break;
        }
        if (!empty($data['currentPage'])) {
            $query = $query->orderBy('a.id', 'desc')
                ->paginate($data['pageSize'], ['*'], '', $data['currentPage'])->toArray();

        } else {
            $query = $query->orderBy('a.id', 'desc')->get()->toArray();
            $query['data'] = $query;

        }

        if (!empty($query['data'])) {
            foreach ($query['data'] as &$value) {
                if (!empty($value['barter_goods_detail_info'])) {
                    foreach ($value['barter_goods_detail_info'] as $k => $val) {
                        $storageManageInfo = StorageManageModel::select(
                            'id',
                            'in_storage_num'
                        )
                            ->where([
                                'shelf_id' => $val['shelf_id'],
                                'location_id' => $val['location_id'],
                                'type_id' => $val['type_id'],
                                'storage_id' => $val['storage_id'],
                                'delete_flag' => 0
                            ])->first();
                        $val['storage_manage_id'] = $storageManageInfo['id'] ?? '';
                        $val['in_storage_num'] = $storageManageInfo['in_storage_num'] ?? 0;
                    }
                }
                $value['return_goods_detail_info'] = [];
                if (!empty($value['return_id'])) {
                    $returnGoodsDetail = SalesReturnGoodsDetailModel::select(
                        'a.id as return_goods_id',
                        'c.materiel_name',
                        'c.type_name',
                        'c.materiel_no',
                        'c.materiel_img',
                        'c.materiel_unit',
                        'price',
                        'a.num',
                        'a.in_num',
                        'b.storage_name',
                        'b.id as storage_id',
                        'return_id',
                        'cost_price',
                        'a.remark',
                        'a.materiel_type_id as type_id',
                        'a.shelf_id',
                        'a.location_id',
                        'se.shelf_name',
                        'lo.location_name',
                        'c.is_product_materiel'
                    )->from('sales_return_goods_detail as a')
                        ->leftJoin('materiel_type as c', 'c.id', '=', 'a.materiel_type_id')
                        ->leftJoin('storage as b', 'b.id', '=', 'a.warehouse_id')
                        ->leftJoin('storage_shelf as se', 'a.shelf_id', '=', 'se.id')
                        ->leftJoin('storage_shelf_location as lo', 'a.location_id', '=', 'lo.id')
                        ->where([
                            'se.status' => 1,
                            'lo.status' => 1,
                            'a.delete_flag' => 0,
                            'b.delete_flag' => 0,
                            'c.delete_flag' => 0,
                            'a.main_id' => $data['main_id'],
                            'return_id' => $value['return_id'],
                        ])->get()->toArray();
                    if (!empty($returnGoodsDetail)) {
                        foreach ($returnGoodsDetail as &$rVal) {
                            $storageManageInfo = StorageManageModel::select(
                                'id',
                                'in_storage_num'
                            )->where([
                                'shelf_id' => $rVal['shelf_id'],
                                'location_id' => $rVal['location_id'],
                                'type_id' => $rVal['type_id'],
                                'storage_id' => $rVal['storage_id'],
                                'delete_flag' => 0
                            ])->first();
                            $rVal['storage_manage_id'] = $storageManageInfo['id'] ?? '';
                            $rVal['in_storage_num'] = $storageManageInfo['in_storage_num'] ?? 0;
                        }
                    }
                    $value['return_goods_detail_info'] = $returnGoodsDetail ?? [];
                }

                $value['customer_phone'] = '';
                if (!empty($value['customer_id'])) {
                    $value['customer_phone'] = SupplierCustomerModel::query()
                        ->where('id', $value['customer_id'])->value('phone') ?? '';
                }
            }
        }
        if (empty($data['currentPage'])) {
            $query = $query['data'];
        }
        return $query;
    }

    static private function barterReturnKeyWordList($returnGoodsInfo, $barterGoodsInfo, $userId, $data)
    {
        $barterIdArr = [];
        $barterGoodsIdArr = [];
        if (!empty($returnGoodsInfo)) {
            $returnIdArr = array_unique(array_column($returnGoodsInfo, 'id'));
            $returnList = SalesReturnModel::select('b.id as barter_id')
                ->from('sales_return as a')
                ->leftJoin('barter as b', 'b.barter_return_no', '=', 'a.barter_return_no')
                ->where([
                    'a.delete_flag' => 0,
                    'b.delete_flag' => 0,
                    'a.main_id' => $data['main_id']
                ])->whereIn('a.id', $returnIdArr)
                ->get()->toArray();

            if (!empty($returnList)) {
                $barterIdArr = array_unique(array_column($returnList, 'barter_id'));
            }
        }
        if (!empty($barterGoodsInfo)) {
            $barterIdArr = array_unique(array_merge($barterIdArr, array_column($barterGoodsInfo, 'id')));

        }

        return self::commonSearchWithKeyword($userId, $data, $barterIdArr);
    }

    //重新下单
    static public function addAgain($data)
    {
        DB::beginTransaction();
        try {
            //新增换货单
            $barterInfo = BarterModel::find($data['id'])->toArray();
            $barterData = $barterInfo;
            unset($barterData['id']);
            $barterData['user_id'] = $data['user_id'];
            $barterData['repeal_status'] = 0;
            $barterData['real_money'] = 0;
            $barterData['out_status'] = 0;
            $barterData['pay_status'] = 0;
            $barterData['order_no'] = 'TH' . $data['main_id'] . TimeUtil::getMillisecond();//订单号
            $barterData['created_at'] = $data['logTime'];
            $barterData['barter_date'] = $data['logTime'];
            $barterData['deliver_time'] = "";
            $barterData['barter_return_no'] = 'BR' . $data['main_id'] . TimeUtil::getMillisecond();//换货与退货共同关联编号
            $barterId = BarterModel::insertGetId($barterData);
            //商品详细
            $barterGoods = BarterGoodsDetailModel::where([
                'barter_id' => $data['id'],
                'delete_flag' => 0
            ])->get()->toArray();
            if (!empty($barterGoods)) {
                foreach ($barterGoods as $val) {
                    $val['created_at'] = $data['logTime'];
                    $val['out_num'] = 0;
                    $val['is_out'] = 0;
                    $val['barter_id'] = $barterId;
                    unset($val['id']);
                    BarterGoodsDetailModel::insertGetId($val);
                }
            }
            //司机
            $barterDriver = BarterDriverModel::select(
                'plate_number',
                'name',
                'phone',
                'logistics_company',
                'remark',
                'plate_image',
                'id_card_image',
                'driving_licence',
                'main_id'
            )->where('barter_id', $data['id'])->get()->toArray();
            if (!empty($barterDriver)) {
                foreach ($barterDriver as &$bVal) {
                    $bVal['barter_id'] = $barterId;
                    $bVal['created_at'] = $data['logTime'];
                }
                BarterDriverModel::insert($barterDriver);
            }
            //其他费用
            $barterOtherCharges = BarterOtherChargesModel::select(
                'money',
                'other_type_name',
                'other_remark',
                'main_id'
            )->where('barter_id', $data['id'])->get()->toArray();
            if ($barterOtherCharges) {
                foreach ($barterOtherCharges as &$value1) {
                    $value1['barter_id'] = $barterId;
                    $value1['created_at'] = $data['logTime'];
                }
                BarterOtherChargesModel::insert($barterOtherCharges);
            }

            $barterLogisticsList = BarterLogisticsInfoModel::select(
                'main_id',
                'logistics_company',
                'logistics_order_no'
            )->where(
                'barter_id', $data['id']
            )->get()->toArray();

            if (!empty($barterLogisticsList)) {
                foreach ($barterLogisticsList as &$lVal) {
                    $lVal['barter_id'] = $barterId;
                    $lVal['user_id'] = $data['user_id'];
                    $lVal['created_at'] = $data['logTime'];
                }
                BarterLogisticsInfoModel::insert($barterLogisticsList);
            }

            //新增退货单
            $returnInfo = SalesReturnModel::where(
                'barter_return_no',
                $barterInfo['barter_return_no']
            )->first()->toArray();
            $returnData = $returnInfo;
            unset($returnData['id']);
            $returnData['real_money'] = 0;
            $returnData['out_status'] = 0;
            $returnData['pay_status'] = 0;
            $returnData['repeal_status'] = 0;
            $returnData['user_id'] = $data['user_id'];
            $returnData['created_at'] = $data['logTime'];
            $returnData['refund_date'] = $data['logTime'];
            $returnData['barter_return_no'] = $barterData['barter_return_no'];//换货与退货共同关联编号
            $returnData['order_no'] = 'ST' . $data['main_id'] . TimeUtil::getMillisecond();//订单号
            $returnId = SalesReturnModel::insertGetId($returnData);

            unset($returnData);
            //商品详细
            $returnGoods = SalesReturnGoodsDetailModel::where([
                'delete_flag' => 0,
                'return_id' => $returnInfo['id']
            ])->get()->toArray();
            if (!empty($returnGoods)) {
                foreach ($returnGoods as $val) {
                    $val['in_num'] = 0;
                    $val['is_in'] = 0;
                    $val['return_id'] = $returnId;
                    $val['created_at'] = $data['logTime'];
                    unset($val['id']);
                    SalesReturnGoodsDetailModel::insertGetId($val);
                }
            }
            $returnLogisticsList = SalesReturnLogisticsInfoModel::select(
                'main_id',
                'logistics_company',
                'logistics_order_no'
            )->where(
                'return_id', $returnInfo['id']
            )->get()->toArray();
            if (!empty($returnLogisticsList)) {
                foreach ($returnLogisticsList as &$lVal) {
                    $lVal['return_id'] = $returnId;
                    $lVal['user_id'] = $data['user_id'];
                    $lVal['created_at'] = $data['logTime'];
                }
                SalesReturnLogisticsInfoModel::insert($returnLogisticsList);
            }
            $logData = '换货号：' . $barterInfo['order_no'] . '创建成功!';
            CommonService::log('换货单-重新下单', $barterInfo, $logData);
            DB::commit();
            return ['code' => 0, 'msg' => 'success', 'data' => ''];
        } catch (\Exception $e) {
            DB::rollBack();
            Log::debug('换货单-重新下单:' . var_export($e->getMessage(), true));
            return ['code' => 1, 'msg' => $e->getMessage(), 'data' => ''];
        }
    }

    /**
     * 换货详情
     * @param unknown $id
     * @return number
     */
    static public function detail($id)
    {
        $barterInfo = BarterModel::select(
            'a.id',
            'a.money',
            'a.remark',
            'a.out_status',
            'a.pay_status',
            'a.customer_id',
            'barter_date',
            'a.order_no',
            'a.out_order_no',
            'a.customer_name',
            'a.barter_return_no',
            'a.general_remarks',
            'a.approver_id',
            'spread_price',
            'a.other_charges',
            'c.username as approver_name',
            'b.nickname',
            'b.username',
            'a.source',
            'd.out_status as in_status',
            'a.main_id'
        )->from('barter as a')
            ->leftJoin('admin as b', 'b.id', '=', 'a.user_id')
            ->leftJoin('admin as c', 'c.id', '=', 'a.approver_id')
            ->leftJoin('sales_return as d', 'd.barter_return_no', '=', 'a.barter_return_no')
            ->where([
                'a.id' => $id,
                'a.delete_flag' => 0
            ])->first();

        if (!empty($barterInfo)) {
            $barterRes = SELF::barterAndReturnDetail($barterInfo['id'], true);
            if (!empty($barterRes['code'])) {
                return $barterRes;
            } else {
                $barterInfo['barter_info'] = $barterRes['data'];
            }
            $returnId = SalesReturnModel::where([
                'delete_flag' => 0,
                'barter_return_no' => $barterInfo['barter_return_no']
            ])->value('id');

            if (!empty($returnId)) {
                $returnRes = SELF::barterAndReturnDetail($returnId);
                if (!empty($barterRes['code'])) {
                    return $barterRes;
                } else {
                    $barterInfo['return_info'] = $returnRes['data'];
                }
            }
            $barterInfo['check_info'] = CheckModel::select(
                'id',
                'type',
                'all_id',
                'status',
                'eudit_status',
                'order_no'
            )->where([
                'all_id' => $barterInfo['id'],
                'type' => 4,
                'repeal_status' => 0
            ])->first() ?? [];
            $adminInfo = AdminModel::query()->select()
                ->where([
                    'id' => $barterInfo['main_id']
                ])->first();
            $barterInfo['company_name'] = $adminInfo['company_name'] ?? '';
            $barterInfo['company_logo_img'] = $adminInfo['company_logo_img'] ?? '';
            $barterInfo['company_address'] = $adminInfo['company_address'] ?? '';
            return ['code' => 0, 'msg' => 'success', 'data' => $barterInfo];
        } else {
            return ['code' => 1, 'msg' => '换货信息，没有找到！', 'data' => ''];
        }
    }

    /**
     * 撤销
     */
    public static function repeal($data): ?array
    {
        $barterInfo = BarterModel::where('id', $data['id'])->first();
        if (empty($barterInfo)) {
            return ['code' => 1, 'msg' => '要撤销的换货单，没有找到！', 'data' => ''];
        }
        if (!empty($barterInfo['delete_flag'])) {
            return ['code' => 1, 'msg' => '换货单已经删除，不能撤销！', 'data' => ''];
        }
        /* if($barterInfo['out_status'] == 2){
             return ['code'=>1,'msg'=>'换货单已经全部出库，不能撤销！','data'=>''];
         }*/
        if ($barterInfo['repeal_status'] == 1) {
            return ['code' => 1, 'msg' => '换货单，已经撤销！', 'data' => ''];
        }
        $returnInfo = SalesReturnModel::where([
            'barter_return_no' => $barterInfo['barter_return_no']
        ])->first();
        if (!empty($returnInfo)) {
            if (!empty($returnInfo['delete_flag'])) {
                return ['code' => 1, 'msg' => '退信息已经删除，不能撤销！', 'data' => ''];
            }
            /*  if($returnInfo['out_status'] == 2){
                  return ['code'=>1,'msg'=>'退货单已经全部入库，不能撤销！','data'=>''];
              }*/

            if ($barterInfo['repeal_status'] == 1) {
                return ['code' => 1, 'msg' => '退货单，已经撤销！', 'data' => ''];
            }
        }
        DB::beginTransaction();
        try {
            if ($barterInfo['out_status'] == 2) {//已出库
                $outLogList = LogOutStorageModel::query()->where([
                    'main_id' => $data['main_id'],
                    'all_id_type' => 6,
                    'all_id' => $barterInfo['id']
                ])->get();
                if (!empty($outLogList)) {
                    foreach ($outLogList->toArray() as $oVal) {
                        if (!empty($oVal['batch_no'])) {//批次号返回
                            $batchArr = $oVal['batch_no'];
                            $StorageBatchModel = StorageBatchModel::query()
                                ->where([
                                    'main_id' => $data['main_id'],
                                    'storage_manage_id' => $oVal['curr_storage_manage_id']
                                ]);
                            if (strpos($oVal['batch_no'], ',') !== false) {
                                $batchArr = explode(',', $oVal['batch_no']);
                            }
                            if (is_array($batchArr)) {
                                $StorageBatchModel->whereIn('batch_no', $batchArr);
                            } else {
                                $StorageBatchModel->where('batch_no', $batchArr);
                            }
                            $StorageBatchModel->increment('batch_left_num', $oVal['operate_num']);
                        }
                        $oVal->is_cancel = 1;
                        $oVal->save();
                        $StorageManageModel = StorageManageModel::query()->where([
                            'main_id' => $data['main_id'],
                            'id' => $oVal['curr_storage_manage_id']
                        ])->increment('in_storage_num', $oVal['operate_num']);

                        $isSerial = MaterielTypeModel::query()->where([
                            'main_id' => $data['main_id'],
                            'type_id' => $oVal['materiel_type_id']
                        ])->value('is_use_serial');
                        if ($isSerial) {//开启序列号的返回序列号
                            $outSerialInfo = BarterOutSerialNumberModel::query()->where([
                                'main_id' => $data['main_id'],
                                'type_id' => $oVal['materiel_type_id'],
                                'barter_id' => $barterInfo['id']
                            ])->get();
                            if (!empty($outSerialInfo)) {
                                foreach ($outSerialInfo as $bVal) {
                                    SerialNumberModel::query()
                                        ->where('id', $bVal['serial_id'])->update(['status' => 1]);
                                    $bVal->delete_flag = 1;
                                    $bVal->save();
                                }
                            }
                        }
                    }
                }
            } else {//未出库
                $goodsList = BarterGoodsDetailModel::query()
                    ->where('barter_id', $barterInfo['id'])->get();
                if (!empty($goodsList)) {
                    foreach ($goodsList->toArray() as $gVal) {
                        $StorageManageModel = StorageManageModel::query()->where([
                            'main_id' => $data['main_id'],
                            'storage_id' => $gVal['storage_id'],
                            'type_id' => $gVal['type_id'],
                            'shelf_id' => $gVal['shelf_id'],
                            'location_id' => $gVal['location_id']
                        ])->decrement('virtual_storage_num', $gVal['num']);
                    }
                }
            }
            BarterModel::where('id', $barterInfo['id'])->update(['repeal_status' => 1]);
            BarterGoodsDetailModel::where('barter_id', $barterInfo['id'])->update(['repeal_status' => 1]);
            CheckModel::where([
                'main_id' => $data['main_id'],
                'all_id' => $barterInfo['id'],
                'type' => 4
            ])->update([
                'repeal_status' => 1
            ]);//更新销售审批状态
            TallyModel::where([
                'remark' => '换货',
                'main_id' => $data['main_id'],
                'order_no' => $barterInfo['order_no']
            ])->update([
                'delete_flag' => 1
            ]);
            if (!empty($returnInfo)) {
                if ($returnInfo['out_status'] == 2) {//退货入库
                    $inLogList = LogInStorageModel::query()->where([
                        'main_id' => $data['main_id'],
                        'all_id_type' => 9,
                        'all_id' => $returnInfo['id']
                    ])->get();
                    if (!empty($inLogList)) {
                        foreach ($inLogList->toArray() as $iVal) {
                            if (!empty($iVal['batch_no'])) {//批次号返回
                                $batchArr = $iVal['batch_no'];
                                $StorageBatchModel = StorageBatchModel::query()
                                    ->where([
                                        'main_id' => $data['main_id'],
                                        'storage_manage_id' => $iVal['curr_storage_manage_id']
                                    ]);
                                if (strpos($iVal['batch_no'], ',') !== false) {
                                    $batchArr = explode(',', $iVal['batch_no']);
                                }
                                if (is_array($batchArr)) {
                                    $StorageBatchModel->whereIn('batch_no', $batchArr);
                                } else {
                                    $StorageBatchModel->where('batch_no', $batchArr);
                                }
                                $StorageBatchModel->decrement('batch_left_num', $iVal['operate_num']);
                            }
                            LogInStorageModel::query()->where([
                                'main_id' => $data['main_id'],
                                'id' => $iVal['id']
                            ])->update(['is_cancel'=>1]);
                            $StorageManageModel = StorageManageModel::query()->where([
                                'main_id' => $data['main_id'],
                                'id' => $iVal['curr_storage_manage_id']
                            ])->decrement('in_storage_num', $iVal['operate_num']);

                            $isSerial = MaterielTypeModel::query()->where([
                                'main_id' => $data['main_id'],
                                'id' => $iVal['materiel_type_id']
                            ])->value('is_use_serial');
                            if ($isSerial) {//开启序列号的返回序列号
                                $outSerialInfo = SalesOutSerialNumberModel::query()
                                    ->where([
                                        'main_id' => $data['main_id'],
                                        'type_id' => $iVal['materiel_type_id'],
                                        'return_id' => $returnInfo['id']
                                    ])->get();
                                if (!empty($outSerialInfo)) {
                                    foreach ($outSerialInfo as $oVal) {
                                        SerialNumberModel::query()
                                            ->where('id', $oVal['serial_id'])
                                            ->update([
                                                'status' => 0,
                                                'delete_flag' => 1
                                            ]);
                                        $oVal->delete_flag = 1;
                                        $oVal->save();
                                    }
                                }
                            }
                        }
                    }
                }
                SalesReturnModel::where('id', $returnInfo['id'])->update(['repeal_status' => 1]);
                CheckModel::where([
                    'main_id' => $data['main_id'],
                    'all_id' => $returnInfo['id'],
                    'type' => 5
                ])->update([
                    'repeal_status' => 1
                ]);//更新销售审批状态
                TallyModel::where([
                    'remark' => '退货',
                    'main_id' => $data['main_id'],
                    'order_no' => $returnInfo['order_no']
                ])->update([
                    'delete_flag' => 1
                ]);
            }
            $logData = '换货号：' . $barterInfo['order_no'] . '，撤销成功！';
            CommonService::log('撤销换货单', $barterInfo, $logData);
            DB::commit();
            return ['code' => 0, 'msg' => 'success', 'data' => ''];
        } catch (\Exception $e) {
            DB::rollBack();
            Log::debug('撤销换货单异常：' . var_export($e->getMessage(), true));
            return ['code' => 1, 'msg' => $e->getMessage(), 'data' => ''];
        }
    }

    //换货和退货详情
    static public function barterAndReturnDetail($id, $type = 0)
    {
        $title = '换货';
        if ($type) {
            $info = BarterModel::getBarterInfo($id);
            $info['logistics_info'] = $info['barter_logistics_info'] ?? [];
            unset($info['barter_logistics_info']);
        } else {
            $title = '退货';
            $info = SalesReturnModel::getsalesReturnInfo($id);
            $info['logistics_info'] = $info['return_logistics_info'] ?? [];
            unset($info['return_logistics_info']);
        }
        if (empty($info)) {
            return ['code' => 1, 'msg' => $title . '单信息，没有找到！', 'data' => ''];
        }

        if (!empty($info['logistics_info'])) {
            foreach ($info['logistics_info'] as &$val) {
                $val['logistics_order_no'] = !empty($val['logistics_order_no']) ?
                    explode(',', $val['logistics_order_no']) : [];
            }
        }
        if ($type) {
            $goodsInfo = BarterGoodsDetailModel::detail($id);
        } else {
            $goodsInfo = SalesReturnGoodsDetailModel::detail($id);
        }
        $totalNum = 0;
        $totalPrice = 0;
        if (empty($info)) {
            $info['goods_list'] = [];
        } else {
            $goodsDetail = [];
            foreach ($goodsInfo as $key => $materielValue) {
                if ($materielValue['location_id'] != 0) {
                    $storageManageInfo = StorageManageModel::where([
                        'type_id' => $materielValue['type_id'],
                        'storage_id' => $materielValue['storage_id'],
                        'location_id' => $materielValue['location_id']
                    ])->first();
                } else {
                    $storageManageInfo = StorageManageModel::where([
                        'type_id' => $materielValue['type_id'],
                        'storage_id' => $materielValue['storage_id']
                    ])->first();
                }
                if (!empty($type)) {
                    $serialList = BarterOutSerialNumberModel::select(
                        'id as barter_serial_id',
                        'serial_number'
                    )->where([
                        'delete_flag' => 0,
                        'barter_id' => $id,
                        'type_id' => $materielValue['type_id'],
                    ])->get()->toArray();
                } else {
                    $serialList = SalesOutSerialNumberModel::select(
                        'id as return_serial_id',
                        'serial_number'
                    )->where([
                        'delete_flag' => 0,
                        'return_id' => $id,
                        'type_id' => $materielValue['type_id']
                    ])->get()->toArray();
                }
                $materielImg = '';
                if (!empty($materielValue['materiel_img'])) {
                    $materielImgArr = array_filter(explode(',',
                        $materielValue['materiel_img']),
                        function ($v) {
                            return $v !== '';
                        });

                    $materielImg = $materielImgArr[0];
                }
                $materielContentId = [];
                if ($materielValue['is_product_materiel']) {
                    $materielContentId = MaterielProductContentModel::where(
                        'product_id',
                        $materielValue['type_id']
                    )->pluck('type_id');
                }
                $goodsDetail[$key] = [
                    'materiel_unit' => $materielValue['materiel_unit'],
                    'is_product_materiel' => $materielValue['is_product_materiel'],
                    'type_id' => $materielValue['type_id'],
                    'serial_number_list' => $serialList ?? [],
                    'name' => $materielValue['materiel_name'],
                    'type_name' => $materielValue['type_name'],
                    'price' => $materielValue['price'],
                    'cost_price' => $materielValue['cost_price'],
                    'num' => $materielValue['num'],
                    'remark' => $materielValue['remark'],
                    'materiel_no' => $materielValue['materiel_no'],
                    'image' => empty($materielImg) ? '' : $materielImg,
                    'storage_name' => $materielValue['storage_name'],
                    'storage_id' => $materielValue['storage_id'],
                    'piece' => $materielValue['piece'] ?? 0,
                    'materiel_class_id' => $materielValue['materiel_class_id'],
                    'shelf_id' => $materielValue['shelf_id'],
                    'location_id' => $materielValue['location_id'],
                    'shelf_name' => empty($materielValue['shelf_name']) ? '' : $materielValue['shelf_name'],
                    'location_name' => empty($materielValue['location_name']) ? '' : $materielValue['location_name'],
                    'storage_manage_id' => empty($storageManageInfo) ? 0 : $storageManageInfo['id'],
                    'in_storage_num' => empty($storageManageInfo) ? 0 : $storageManageInfo['in_storage_num'],
                    'is_use_serial' => $materielValue['is_use_serial'],
                    'content_type_id' => $materielContentId,
                    'batch_list' => !empty($materielValue['batch_info']) ? json_decode($materielValue['batch_info'], true) : [],
                    'texture' => $materielValue['texture'],
                    'executive_standard' => $materielValue['executive_standard']
                ];
                $totalNum += $materielValue['num'];
                if (!empty($type)) {
                    $goodsDetail[$key]['barter_goods_id'] = $materielValue['barter_goods_id'];
                    $goodsDetail[$key]['out_num'] = $materielValue['out_num'];
                    $goodsDetail[$key]['one_subtotal'] = $materielValue['num'] * $materielValue['price'];
                    $totalPrice += $materielValue['num'] * $materielValue['price'];
                } else {
                    $goodsDetail[$key]['in_num'] = $materielValue['in_num'];
                    $totalPrice += $materielValue['num'] * $materielValue['cost_price'];
                    $goodsDetail[$key]['return_goods_id'] = $materielValue['return_goods_id'];
                    $goodsDetail[$key]['one_subtotal'] = $materielValue['num'] * $materielValue['cost_price'];
                }
            }
            $info['total_num'] = $totalNum;
            $info['total_price'] = $totalPrice;
            $info['goods_list'] = $goodsDetail;
        }
        return ['code' => 0, 'msg' => '', 'data' => $info];
    }

    /**
     * 换货出库
     * @param array $data
     * @param unknown $isUseShelf
     */
    public static function barterOut(array $data, $isUseShelf, $batchTitle = '')
    {
        $barterInfo = BarterModel::where([
            'id' => $data['id'],
            'main_id' => $data['main_id']
        ])->first();
        if (empty($barterInfo)) {
            return ['code' => 1, 'msg' => '要出库的退换货单，没有找到！', 'data' => ''];
        }
        if (!empty($barterInfo['delete_flag'])) {
            return ['code' => 1, 'msg' => '退换货单已经删除，不能出库！', 'data' => ''];
        }
        if ($barterInfo['repeal_status'] == 1) {
            return ['code' => 1, 'msg' => '退换货单已经撤销，无法出库！', 'data' => ''];
        }
        if ($barterInfo['out_status'] == 2) {
            return ['code' => 1, 'msg' => '退换货单已经出库了！', 'data' => ''];
        }
        $checkInfo = CheckModel::where([
            'all_id' => $barterInfo['id'],
            'type' => 4,
            'repeal_status' => 0
        ])->first();
        if (!empty($checkInfo)) {
            if (empty($checkInfo['eudit_status'])) {
                return ['code' => 1, 'msg' => '退换货单在待审批中！', 'data' => ''];
            }
            if ($checkInfo['eudit_status'] == 2) {
                return ['code' => 1, 'msg' => '退换货单未审批通过！', 'data' => ''];
            }
        }
        $goodsList = BarterGoodsDetailModel::select(
            'a.id',
            'b.id as goods_id',
            'b.materiel_name as goods_name',
            'b.materiel_no',
            'b.type_name',
            'a.price',
            'a.cost_price',
            'a.num',
            'a.storage_id',
            'a.remark',
            'b.materiel_class_id',
            'c.class_name',
            'c.class_no',
            'e.id as shelf_id',
            'e.shelf_name',
            'f.id as location_id',
            'f.location_name',
            'd.id as storage_id',
            'd.storage_name',
            'd.storage_address',
            'b.is_use_serial',
            'b.is_product_materiel',
            'a.batch_info'
        )->from('barter_goods_detail as a')
            ->leftJoin('materiel_type as b', 'b.id', '=', 'a.type_id')
            ->leftJoin('materiel_class as c', 'c.id', '=', 'b.materiel_class_id')
            ->leftJoin('storage as d', 'd.id', '=', 'a.storage_id')
            ->leftJoin('storage_shelf as e', 'e.id', '=', 'a.shelf_id')
            ->leftJoin('storage_shelf_location as f', 'f.id', '=', 'a.location_id')
            ->where([
                'e.status' => 1,
                'f.status' => 1,
                'a.delete_flag' => 0,
                'b.delete_flag' => 0,
                'c.delete_flag' => 0,
                'd.delete_flag' => 0,
                'a.repeal_status' => 0,
                'a.main_id' => $data['main_id'],
                'barter_id' => $barterInfo['id']
            ])->get()->toArray();

        $batchArr = [];
        DB::beginTransaction();
        try {
            if (!empty($goodsList)) {
                foreach ($goodsList as $gVal) {
                    if (empty($gVal['goods_id'])) {
                        throw new Exception('商品信息异常');
                    }
                    if (empty($gVal['storage_id'])) {
                        throw new Exception('商品:' . $gVal['goods_name'] . ',没有找到仓库！');
                    }
                    if (empty($gVal['materiel_class_id'])) {
                        throw new Exception('商品:' . $gVal['goods_name'] . ',没有分类信息！');
                    }
                    if (empty($gVal['shelf_id'])) {
                        throw new Exception('商品:' . $gVal['goods_name'] . '的仓库' . $gVal['storage_name'] . '，没有货架信息！');
                    }
                    if (empty($gVal['location_id'])) {
                        throw new Exception('商品:' . $gVal['goods_name'] . '的仓库' . $gVal['storage_name'] . '，没有库位信息！');
                    }

                    $storageCond = [
                        'delete_flag' => 0,
                        'main_id' => $data['main_id'],
                        'type_id' => $gVal['goods_id'],
                        'storage_id' => $gVal['storage_id']
                    ];
                    if (!empty($isUseShelf)) {
                        $storageCond['shelf_id'] = $gVal['shelf_id'];
                        $storageCond['location_id'] = $gVal['location_id'];
                    }
                    $storageManageInfo = StorageManageModel::select(
                        'id',
                        'in_storage_num',
                        'alert_num',
                        'materiel_mean_cost'
                    )->where($storageCond)->first();

                    if (empty($storageManageInfo)) {
                        throw new Exception('商品:' . $gVal['goods_name'] . '的仓库' . $gVal['storage_name'] . '，没有库存信息！');
                    }
                    if (!OperMainAccountModel::query()
                        ->where([
                            'main_id' => $data['main_id'],
                            'delete_flag' => 0
                        ])->exists()) {
                        if ($storageManageInfo['in_storage_num'] < $gVal['num']) {
                            return ['code' => 1,
                                'msg' => '商品:' . $gVal['goods_name'] . '-' .
                                    $gVal['type_name'] .
                                    '当前库存剩余数量' . $storageManageInfo['in_storage_num'] . '不足，无法完成出库',
                                'data' => ''
                            ];
                        }
                    }
                    $serialNoList = "";
                    if (!empty($gVal['is_use_serial'])) {
                        $serialNoList = BarterOutSerialNumberModel::select(
                            'id',
                            'serial_id',
                            'serial_number'
                        )->where([
                            'status' => 1,
                            'main_id' => $data['main_id'],
                            'barter_id' => $barterInfo['id'],
                            'type_id' => $gVal['goods_id']
                        ])->get()->toArray();
                        if (!empty($serialNoList)) {
                            foreach ($serialNoList as $sVal) {
                                $serialInfo = SerialNumberModel::select('id', 'status')
                                    ->where([
                                        'id' => $sVal['serial_id'],
                                        'main_id' => $data['main_id'],
                                        'delete_flag' => 0
                                    ])->first();
                                if (empty($serialInfo)) {
                                    throw new Exception('商品:' . $gVal['goods_name'] . '的序列号（' . $sVal['serial_number'] . '）,不存在');
                                }
                                if (empty($serialInfo['status'])) {//1是未使用，0是使用
                                    throw new Exception('商品:' . $gVal['goods_name'] . '的序列号（' . $sVal['serial_number'] . '），已使用！');
                                }
                                BarterOutSerialNumberModel::where('id', $sVal['id'])->update(['status' => 0]);//1是未使用，0是使用
                                SerialNumberModel::where('id', $serialInfo['id'])->update(['status' => 0]);//1是未使用，0是使用
                            }
                            $serialNoList = join(',', array_column($serialNoList, 'serial_number'));
                        } else {
                            throw new Exception('商品:' . $gVal['goods_name'] . ',请选择序列号出库！');
                        }
                    }

                    $surplusNum = 0;
                    if (!empty($gVal['batch_info'])) {//批次号管理
                        $batchList = json_decode($gVal['batch_info'], true);
                        foreach ($batchList as $bVal) {
                            $storageInfo = StorageBatchModel::query()->where([
                                'id' => $bVal['batch_id']
                            ])->first();
                            $batchNum = $storageInfo->batch_left_num - $bVal['batch_num'];
                            if ($batchNum < 0) {
                                $surplusNum += abs($batchNum);
                                $batchNum = 0;
                            }
                            $storageInfo->batch_left_num = $batchNum;
                            $storageInfo->save();
                            $batchArr[] = $bVal['batch_no'];
                        }
                    }
                    if (!empty($surplusNum) || empty($gVal['batch_info'])) {
                        $batchInfo = [
                            'storage_manage_id' => $storageManageInfo['id'],
                            'batch_cost' => $gVal['cost_price'],
                            'main_id' => $data['main_id']
                        ];
                        $surplusNum = !empty($surplusNum) ? $surplusNum : $gVal['num'];
                        $batchArr[] = StorageManageService::createBatchNo($batchInfo, $surplusNum, $batchTitle);
                    }
                    $outLogData = [
                        'type' => 9,
                        'storage_id' => $gVal['storage_id'],
                        'batch_no' => !empty($batchArr) ? implode(',', $batchArr) : '',
                        'client_id' => $barterInfo['customer_id'],
                        'storage_name' => $gVal['storage_name'],
                        'storage_address' => $gVal['storage_address'],
                        'curr_storage_manage_id' => $storageManageInfo['id'],
                        'materiel_class_id' => $gVal['materiel_class_id'],
                        'materiel_class_name' => $gVal['class_name'],
                        'materiel_class_no' => $gVal['class_no'],
                        'materiel_type_id' => $gVal['goods_id'],
                        'materiel_name' => $gVal['goods_name'],
                        'type_name' => $gVal['type_name'],
                        'materiel_no' => $gVal['materiel_no'],
                        'operate_num' => $gVal['num'],
                        'last_storage_num' => $storageManageInfo['in_storage_num'],
                        'next_storage_num' => $storageManageInfo['in_storage_num'] - $gVal['num'],
                        'sell_price' => $gVal['price'],
                        'materiel_mean_cost' => $gVal['cost_price'],
                        'all_id_type' => 6,
                        'remark' => $gVal['remark'],
                        'all_id' => $barterInfo['id'],
                        'serial_number' => $serialNoList,
                        'user_id' => $data['user_id'],
                        'main_id' => $data['main_id'],
                        'out_storage_time' => $data['logTime'],
                        'general_remarks' => $barterInfo['general_remarks'],
                        'fact_out_time' => date('Y-m-d', $data['logTime']),
                        'created_at' => $data['logTime'],
                        'shelf_id' => $gVal['shelf_id'],
                        'location_id' => $gVal['location_id'],
                    ];

                    $barterOutData = [
                        'materiel_type_id' => $gVal['goods_id'],
                        'num' => $gVal['num'],
                        'barter_id' => $barterInfo['id'],
                        'price' => $gVal['price'],
                        'storage_id' => $gVal['storage_id'],
                        'remark' => $gVal['remark'],
                        'shelf_id' => $gVal['shelf_id'],
                        'location_id' => $gVal['location_id'],
                    ];
                    $outLogId = LogOutStorageModel::insertGetId($outLogData);
                    BarterOutStorageModel::insertGetId($barterOutData);
                    StorageManageModel::where('id', $storageManageInfo['id'])->decrement('in_storage_num', $gVal['num']);
                    StorageManageModel::where('id', $storageManageInfo['id'])->decrement('virtual_storage_num', $gVal['num']);
                    BarterGoodsDetailModel::where([
                        'id' => $gVal['id']
                    ])->update([
                        'is_out' => 1,
                        'out_num' => $gVal['num']
                    ]);
                    MessageService::sendAlertSms(
                        $gVal['goods_name'],
                        $gVal['type_name'],
                        $storageManageInfo['in_storage_num'] - $gVal['num'],
                        $storageManageInfo['alert_num'],
                        $datas = [
                            'user_id' => $data['user_id'],
                            'main_id' => $data['main_id']
                        ],
                        $gVal['storage_id'],
                        $gVal['storage_name'],
                        $gVal['num']
                    );

                    MessageService::sendShortSms(
                        $gVal['goods_name'],
                        $gVal['type_name'],
                        $storageManageInfo['in_storage_num'] - $gVal['num'],
                        $datas = [
                            'user_id' => $data['user_id'],
                            'main_id' => $data['main_id']
                        ],
                        $gVal['storage_name'],
                        $gVal['storage_id']
                    );

                    MessageService::sendOutSms(
                        $gVal['goods_name'],
                        $gVal['type_name'],
                        $storageManageInfo['in_storage_num'] - $gVal['num'],
                        $gVal['storage_name'],
                        $gVal['num'],
                        $datas = [
                            'user_id' => $data['user_id'],
                            'main_id' => $data['main_id']
                        ],
                        $gVal['storage_id'],
                        $storageManageInfo['alert_num'],
                        $outLogId
                    );
                }
            }
            BarterModel::where('id', $barterInfo['id'])->update([
                'out_status' => 2,
                'deliver_time' => $data['logTime']
            ]);//全部完成更新状态
            CheckModel::where([
                'type' => 4,
                'main_id' => $data['main_id'],
                'all_id' => $barterInfo['id']
            ])
                ->update([
                    'status' => 1,
                    'out_in_status' => 0
                ]);
            $returnInfo = SalesReturnModel::query()
                ->where(['barter_return_no' => $barterInfo['barter_return_no']])
                ->first();
            if (!SalesReturnGoodsDetailModel::query()
                ->where([
                    'return_id' => $returnInfo['id'],
                    'delete_flag' => 0,
                ])->exists()) {
                $returnInfo->out_status = 2;
                $returnInfo->save();
            }
            $logRes = '换货号：' . $barterInfo['order_no'] . ',出库成功！';
            CommonService::log('退换货出库', $data, $logRes);
            DB::commit();
            return ['code' => 0, 'msg' => 'success', 'data' => ''];
        } catch (\Exception $e) {
            DB::rollBack();
            Log::debug('退换货出库异常：' . var_export($e->getMessage(), true));
            return ['code' => 1, 'msg' => $e->getMessage(), 'data' => ''];
        }
    }

    /**
     * 退货入库前数据处理
     * @param  $data
     */
    static public function returnIn(array $data, $isUseShelf)
    {
        $returnInfo = BarterModel::select(
            'a.id as barter_id',
            'b.barter_return_no',
            'b.id as return_id',
            'b.delete_flag',
            'b.repeal_status',
            'b.out_status',
            'b.order_no',
            'b.customer_id',
            'b.general_remarks',
            'b.created_at'
        )->from('barter as a')
            ->leftJoin(
                'sales_return as b',
                'b.barter_return_no',
                '=',
                'a.barter_return_no'
            )->where([
                'a.id' => $data['id'],
                'b.main_id' => $data['main_id']
            ])->first();

        if (empty($returnInfo['return_id'])) {
            return ['code' => 1, 'msg' => '要入库的退货单，没有找到！', 'data' => ''];
        }
        if (!empty($returnInfo['delete_flag'])) {
            return ['code' => 1, 'msg' => '退货单已经删除，不能出库！', 'data' => ''];
        }
        if ($returnInfo['repeal_status'] == 1) {
            return ['code' => 1, 'msg' => '退货单已经撤销，无法出库！', 'data' => ''];
        }
        if ($returnInfo['out_status'] == 2) {
            return ['code' => 1, 'msg' => '退货单已经入库了！', 'data' => ''];
        }
        $checkInfo = CheckModel::where([
            'all_id' => $returnInfo['return_id'],
            'type' => 5,
            'repeal_status' => 0
        ])->first();

        if (!empty($checkInfo)) {
            if (empty($checkInfo['eudit_status'])) {
                return ['code' => 1, 'msg' => '退换货单在待审批中！', 'data' => ''];
            }
            if ($checkInfo['eudit_status'] == 2) {
                return ['code' => 1, 'msg' => '退换货单未审批通过！', 'data' => ''];
            }
        }
        $goodsList = SalesReturnGoodsDetailModel::select(
            'a.id',
            'b.id as goods_id',
            'b.materiel_name as goods_name',
            'b.materiel_no',
            'b.type_name',
            'a.price',
            'a.cost_price',
            'a.num',
            'a.remark',
            'b.materiel_class_id',
            'c.class_name',
            'c.class_no',
            'e.id as shelf_id',
            'e.shelf_name',
            'f.id as location_id',
            'f.location_name',
            'd.id as storage_id',
            'd.storage_name',
            'd.storage_address',
            'b.is_use_serial',
            'b.is_product_materiel',
            'a.batch_info'
        )->from('sales_return_goods_detail as a')
            ->leftJoin('materiel_type as b', 'b.id', '=', 'a.materiel_type_id')
            ->leftJoin('materiel_class as c', 'c.id', '=', 'b.materiel_class_id')
            ->leftJoin('storage as d', 'd.id', '=', 'a.warehouse_id')
            ->leftJoin('storage_shelf as e', 'e.id', '=', 'a.shelf_id')
            ->leftJoin('storage_shelf_location as f', 'f.id', '=', 'a.location_id')
            ->where([
                'e.status' => 1,
                'f.status' => 1,
                'a.delete_flag' => 0,
                'b.delete_flag' => 0,
                'c.delete_flag' => 0,
                'd.delete_flag' => 0,
                'a.main_id' => $data['main_id'],
                'return_id' => $returnInfo['return_id']
            ])->get();
        $serialData = [];
        DB::beginTransaction();
        try {
            if (!empty($goodsList)) {
                foreach ($goodsList->toArray() as $gVal) {
                    if (empty($gVal['goods_id'])) {
                        throw new Exception('商品信息异常');
                    }
                    if (empty($gVal['storage_id'])) {
                        throw new Exception('商品:' . $gVal['goods_name'] . ',没有找到仓库！');
                    }
                    if (empty($gVal['materiel_class_id'])) {
                        throw new Exception('商品:' . $gVal['goods_name'] . ',没有分类信息！');
                    }
                    if (empty($gVal['shelf_id'])) {
                        throw new Exception('商品:' . $gVal['goods_name'] . '的仓库' . $gVal['storage_name'] . '，没有货架信息！');
                    }
                    if (empty($gVal['location_id'])) {
                        throw new Exception('商品:' . $gVal['goods_name'] . '的仓库' . $gVal['storage_name'] . '，没有库位信息！');
                    }
                    $storageCond = [
                        'delete_flag' => 0,
                        'main_id' => $data['main_id'],
                        'type_id' => $gVal['goods_id'],
                        'storage_id' => $gVal['storage_id']
                    ];
                    if (!empty($isUseShelf)) {
                        $storageCond['shelf_id'] = $gVal['shelf_id'];
                        $storageCond['location_id'] = $gVal['location_id'];
                    }
                    $storageManageInfo = StorageManageModel::select(
                        'id',
                        'in_storage_num',
                        'alert_num'
                    )->where($storageCond)->first();

                    if (empty($storageManageInfo)) {
                        throw new Exception('商品:' . $gVal['goods_name'] . '的仓库' . $gVal['storage_name'] . '，没有库存信息！');
                    }
                    $serialNoList = "";

                    if (!empty($gVal['is_use_serial'])) {
                        $serialNoList = SalesOutSerialNumberModel::select(
                            'id',
                            'serial_number'
                        )->where([
                            'status' => 1,
                            'main_id' => $data['main_id'],
                            'return_id' => $returnInfo['return_id'],
                            'type_id' => $gVal['goods_id']
                        ])->get()->toArray();

                        if (!empty($serialNoList)) {
                            foreach ($serialNoList as $sVal) {
                                $serialInfo = SerialNumberModel::select('id', 'status')
                                    ->where([
                                        'main_id' => $data['main_id'],
                                        'goods_id' => $gVal['goods_id'],
                                        'serial_no' => $sVal['serial_number']
                                    ])->first();
                                if (!empty($serialInfo)) {
                                    throw new Exception('商品:' . $gVal['goods_name'] . '的序列号（' . $sVal['serial_number'] . '）,已存在！');
                                }
                                SalesOutSerialNumberModel::where('id', $sVal['id'])->update(['status' => 0]);//1是未使用，0是使用
                                $serialData[] = [
                                    'status' => 1,
                                    'goods_id' => $gVal['goods_id'],
                                    'main_id' => $data['main_id'],
                                    'created_at' => $data['logTime'],
                                    'serial_no' => $sVal['serial_number'],
                                    'storage_manage_id' => $storageManageInfo['id'],
                                    'package_id' => $gVal['is_product_materiel'] ? $gVal['goods_id'] : 0,
                                    'package_storage_id' => $gVal['is_product_materiel'] ? $storageManageInfo['id'] : 0,
                                ];
                            }
                            $serialNoList = join(',', array_column($serialNoList, 'serial_number'));
                        } else {
                            throw new Exception('商品:' . $gVal['goods_name'] . ',请添加序列号入库！');
                        }
                    }
                    $batchList = [];
                    if (!empty($gVal['batch_info'])) {
                        $bList = json_decode($gVal['batch_info'], true);
                        foreach ($bList as $bVal) {
                            StorageBatchModel::query()->where([
                                'id' => $bVal['batch_id']
                            ])->increment('batch_left_num', $bVal['batch_num']);
                            $batchList[] = $bVal['batch_no'];
                        }
                    } else {
                        $batchInfo = [
                            'storage_manage_id' => $storageManageInfo['id'],
                            'batch_cost' => $gVal['cost_price'],
                            'main_id' => $data['main_id']
                        ];
                        $batchList[] = StorageManageService::createBatchNo($batchInfo, $gVal['num'], $data['batch_title'], 'in');
                    }

                    $inLogData = [
                        'type' => 8,
                        'storage_id' => $gVal['storage_id'],
                        'supplier_id' => $returnInfo['customer_id'],
                        'storage_name' => $gVal['storage_name'],
                        'storage_address' => $gVal['storage_address'],
                        'curr_storage_manage_id' => $storageManageInfo['id'],
                        'materiel_class_id' => $gVal['materiel_class_id'],
                        'materiel_class_name' => $gVal['class_name'],
                        'materiel_class_no' => $gVal['class_no'],
                        'materiel_type_id' => $gVal['goods_id'],
                        'materiel_name' => $gVal['goods_name'],
                        'type_name' => $gVal['type_name'],
                        'materiel_no' => $gVal['materiel_no'],
                        'operate_num' => $gVal['num'],
                        'last_storage_num' => $storageManageInfo['in_storage_num'],
                        'next_storage_num' => $storageManageInfo['in_storage_num'] + $gVal['num'],
                        'materiel_mean_cost' => $gVal['cost_price'],
                        'all_id_type' => 9,
                        'all_id' => $returnInfo['return_id'],
                        'serial_number' => $serialNoList,
                        'remark' => $gVal['remark'],
                        'user_id' => $data['user_id'],
                        'main_id' => $data['main_id'],
                        'in_storage_time' => $data['logTime'],
                        'general_remarks' => $returnInfo['general_remarks'],
                        'created_at' => $data['logTime'],
                        'shelf_id' => $gVal['shelf_id'],
                        'location_id' => $gVal['location_id'],
                        'batch_no' => !empty($batchList) ? implode(',', $batchList) : ''
                    ];

                    $returnOutData = [
                        'materiel_type_id' => $gVal['goods_id'],
                        'num' => $gVal['num'],
                        'name' => $gVal['goods_name'],
                        'return_id' => $returnInfo['return_id'],
                        'price' => $gVal['price'],
                        'warehouse_id' => $gVal['storage_id'],
                        'warehouse' => $gVal['storage_name'],
                        'remark' => $gVal['remark'],
                        'shelf_id' => $gVal['shelf_id'],
                        'location_id' => $gVal['location_id'],
                    ];

                    $inLogId = LogInStorageModel::insertGetId($inLogData);
                    SalesReturnInStorageModel::insertGetId($returnOutData);
                    StorageManageModel::where('id', $storageManageInfo['id'])->increment('in_storage_num', $gVal['num']);
                    //StorageManageModel::where('id', $storageManageInfo['id'])->increment('virtual_storage_num', $gVal['num']);
                    SalesReturnGoodsDetailModel::where([
                        'id' => $gVal['id']
                    ])->update([
                        'is_in' => 1,
                        'in_num' => $gVal['num']
                    ]);
                    MessageService::sendInSms(
                        '',
                        $gVal['goods_name'],
                        $gVal['type_name'],
                        $gVal['storage_id'],
                        $gVal['storage_name'],
                        $data,
                        $gVal['num'],
                        $storageManageInfo['in_storage_num'],
                        $inLogId
                    );
                }
            }
            SerialNumberModel::insert($serialData);
            SalesReturnModel::where(
                'id', $returnInfo['return_id']
            )->update([
                'out_status' => 2,
                'deliver_time' => $data['logTime']
            ]);//全部完成更新状态
            if (!BarterGoodsDetailModel::query()->where([
                'barter_id' => $returnInfo['barter_id'],
                'delete_flag' => 0,
                'repeal_status' => 0
            ])->exists()) {//如果只有退货单商品没有换货单商品，换货单主体直接出库
                BarterModel::query()
                    ->where(['id' => $returnInfo['barter_id']])
                    ->update(['out_status' => 2]);
            }
            CheckModel::where([
                'type' => 5,
                'main_id' => $data['main_id'],
                'all_id' => $returnInfo['return_id']
            ])
                ->update([
                    'status' => 1,
                    'out_in_status' => 0
                ]);
            $logRes = '退货号：' . $returnInfo['order_no'] . ',入库成功！';
            CommonService::log('退换货入库', $data, $logRes);
            DB::commit();
            return ['code' => 0, 'msg' => 'success', 'data' => ''];
        } catch (\Exception $e) {
            DB::rollBack();
            Log::debug('退换货入库异常：' . var_export($e->getMessage(), true));
            return ['code' => 1, 'msg' => $e->getMessage(), 'data' => ''];
        }
    }

    //换货单收款记录
    static public function payHistory($id)
    {
        return BarterModel::select(
            'order_no',
            'expend',
            'collection_time',
            'collection_account',
            'money_flag',
            'a.main_id'
        )->from('barter as a')
            ->leftJoin('barter_pay_record as b', 'a.id', '=', 'b.barter_id')
            ->where('a.id', $id)
            ->get() ?? [];
    }

    /**
     *销售司机列表
     * Author: zlf
     * Created at 2024/1/31 10:48
     * @param $data
     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
     */
    public static function barterDriverList($data)
    {
        return BarterDriverModel::query()->where([
            'main_id' => $data['main_id'],
            'barter_id' => $data['barter_id']
        ])->orderBy('created_at', 'desc')
            ->paginate($data['pageSize'], ['*'], '', $data['currentPage']);
    }

    /**
     *
     * Author: zlf
     * Created at 2024/1/31 14:25
     * @param $data
     * @return mixed
     */
    public static function delBarterDriver($data)
    {
        return BarterDriverModel::query()->where([
            'main_id' => $data['main_id'],
            'barter_id' => $data['barter_id'],
            'id' => $data['driver_id']
        ])->delete();
    }

    /**
     *只修改换货单（客户发货单）
     * Author: zlf
     * Created at 2024/2/2 11:07
     * @param $data
     * @return void
     */
    public static function editSwapOrder($data)
    {
        DB::beginTransaction();
        try {
            $orderData = $data;
            if (!empty($data['goods_info'])) {
                $goodsList = json_decode($data['goods_info'], true);
                if (!is_array($goodsList)) {
                    throw new \Exception('发货商品，数据异常！');
                }

                foreach ($goodsList as $val) {
                    if (empty($val['barter_goods_id'])) {
                        throw new \Exception('商品：' . $val['name'] . '的信息，不存在！');
                    }

                    if (empty($val['piece'])) {
                        throw new \Exception('商品：' . $val['name'] . '的件数不能小于0');
                    }
                    $bool = BarterGoodsDetailModel::query()->where([
                        'id' => $val['barter_goods_id'],
                        'barter_id' => $orderData['id']
                    ])->update([
                        'piece' => $val['piece'],
                        'updated_at' => time()
                    ]);
                }
            } else {
                throw new \Exception('发货商品信息，不能为空');
            }
            unset($orderData['id']);
            unset($orderData['main_id']);
            unset($orderData['goods_info']);
            $orderData['deliver_time'] = strtotime($orderData['deliver_time']);
            BarterModel::query()->where([
                'main_id' => $data['main_id'],
                'id' => $data['id']
            ])->update($orderData);
            DB::commit();
            return ['code' => 0, 'msg' => 'success', 'data' => ''];
        } catch (\Exception $e) {
            DB::rollBack();
            Log::debug('换货客户发货单异常：' . var_export($e->getMessage(), true));
            return ['code' => 1, 'msg' => $e->getMessage(), 'data' => ''];
        }
    }

    public static function getSyncPrice($data)
    {
        return BarterModel::getSyncPrice($data);
    }

    public static function getCount($condition, $date)
    {
        return BarterModel::query()
            ->select(
                DB::raw("SUM(spread_price) as total_spread_price"),
                DB::raw("count(*) as total_count"),
                DB::raw("SUM(other_charges) as barter_other_charges"),
            )
            ->where([
                'delete_flag' => 0,
                'repeal_status' => 0,
            ])->where($condition)
            ->whereBetween('created_at', [$date[0], $date[1]])
            ->first();
    }
}
